Skip to content

用户任务评论管理 - (IFeishuUserV2TaskComments)

功能描述

个人任务评论管理接口,实现评论创建、回复、更新、删除、获取详情等功能。支持用户为自己有权限的任务创建评论或回复评论,并可以获取评论的详细信息。用户可以管理自己创建的评论内容,支持分页查询和排序。该接口使用用户令牌进行认证,确保用户只能操作自己有权限的任务评论。

参考文档

https://open.feishu.cn/document/task-v2/comment/overview

函数列表

函数名称功能描述认证方式HTTP 方法
CreateCommentAsync为一个任务创建个人评论,或者回复该任务的某个评论用户令牌POST
GetCommentByIdAsync给定一个评论的ID,返回个人评论的详情,包括内容、创建人、创建时间和更新时间等信息用户令牌GET
UpdateCommentByIdAsync更新一条个人评论,支持部分字段更新用户令牌PATCH
DeleteCommentByIdAsync删除一条个人评论,删除后将无法进行任何操作,也无法恢复用户令牌DELETE
GetCommentPageListAsync给定一个资源,返回该资源的个人评论列表,支持分页和排序用户令牌GET

函数详细内容

创建评论

函数签名

csharp
Task<FeishuApiResult<CommentOpreationResult>?> CreateCommentAsync(
       [Body] CreateCommentRequest createCommentRequest,
       [Query("user_id_type")] string user_id_type = Consts.User_Id_Type,
       CancellationToken cancellationToken = default);

认证:用户令牌

参数

  • createCommentRequest (CreateCommentRequest): 创建评论请求体,包含评论内容、关联资源信息等
  • user_id_type (string): 用户ID类型,默认值为Consts.User_Id_Type
  • cancellationToken (CancellationToken): 取消操作令牌对象

响应

json
{
  "code": 0,
  "data": {
    "comment": {
      "comment_id": "7198104824246747156",
      "resource_id": "d300a75f-c56a-4be9-80d1-e47653028ceb",
      "resource_type": "task",
      "content": "我已完成第一阶段的开发工作,请审核。",
      "created": "2024-01-01T10:00:00Z",
      "updated": "2024-01-01T10:00:00Z",
      "reply_to_comment_id": null,
      "create_user": {
        "user_id": "user_self",
        "name": "张三",
        "email": "zhangsan@example.com"
      }
    }
  },
  "msg": "success"
}

说明:为一个任务创建评论,或者回复该任务的某个评论。若要创建一个回复评论,需要在创建时设置reply_to_comment_id字段。被回复的评论和新建的评论必须属于同一个任务。用户只能为自己有权限的任务创建评论。

代码示例

typescript
// 创建个人新评论
const createCommentRequest = {
  resource_id: "d300a75f-c56a-4be9-80d1-e47653028ceb",
  resource_type: "task",
  content: "个人进度更新:已完成UI设计部分,正在进行前端开发。"
};

const response = await feishuUserClient.createComment(createCommentRequest);
console.log("个人评论创建成功:", response.data.comment);

// 创建回复评论
const createReplyRequest = {
  resource_id: "d300a75f-c56a-4be9-80d1-e47653028ceb",
  resource_type: "task",
  content: "收到,我会尽快完成剩余的测试工作。",
  reply_to_comment_id: "7198104824246747156"
};

const replyResponse = await feishuUserClient.createComment(createReplyRequest);
console.log("个人评论回复成功:", replyResponse.data.comment);

// 批量创建进度更新评论
async function addProgressUpdates(taskIds: string[], progressStatus: string) {
  const results = [];
  
  for (const taskId of taskIds) {
    try {
      const request = {
        resource_id: taskId,
        resource_type: "task",
        content: `个人进度更新:${progressStatus}`
      };
      
      const response = await feishuUserClient.createComment(request);
      results.push({
        taskId: taskId,
        success: true,
        commentId: response.data.comment.comment_id,
        timestamp: response.data.comment.created
      });
      
      console.log(`任务 ${taskId} 进度更新成功`);
      
      // 添加延迟避免请求过快
      await new Promise(resolve => setTimeout(resolve, 100));
      
    } catch (error) {
      results.push({
        taskId: taskId,
        success: false,
        error: error.message
      });
      
      console.log(`任务 ${taskId} 进度更新失败: ${error.message}`);
    }
  }
  
  return results;
}

// 使用批量更新功能
const taskIds = ["task_1", "task_2", "task_3"];
const progressMessage = "已完成80%的开发工作,预计明日完成全部任务。";
const results = await addProgressUpdates(taskIds, progressMessage);

console.log("批量进度更新结果:");
results.forEach(result => {
  if (result.success) {
    console.log(`✓ 任务 ${result.taskId}: ${result.timestamp}`);
  } else {
    console.log(`✗ 任务 ${result.taskId}: ${result.error}`);
  }
});

// 创建带时间戳的评论模板
function createTimestampedComment(content: string) {
  const timestamp = new Date().toLocaleString('zh-CN');
  return `[${timestamp}] ${content}`;
}

// 使用时间戳模板
const timestampedComment = {
  resource_id: "d300a75f-c56a-4be9-80d1-e47653028ceb",
  resource_type: "task",
  content: createTimestampedComment("开始处理任务,预计2小时后完成。")
};

const timestampedResponse = await feishuUserClient.createComment(timestampedComment);
console.log("带时间戳的评论:", timestampedResponse.data.comment.content);

获取评论详情

函数签名

csharp
Task<FeishuApiResult<CommentOpreationResult>?> GetCommentByIdAsync(
      [Path] string comment_id,
      [Query("user_id_type")] string user_id_type = Consts.User_Id_Type,
      CancellationToken cancellationToken = default);

认证:用户令牌

参数

  • comment_id (string): 要获取评论详情的评论ID,示例值:"7198104824246747156"
  • user_id_type (string): 用户ID类型,默认值为Consts.User_Id_Type
  • cancellationToken (CancellationToken): 取消操作令牌对象

响应

json
{
  "code": 0,
  "data": {
    "comment": {
      "comment_id": "7198104824246747156",
      "resource_id": "d300a75f-c56a-4be9-80d1-e47653028ceb",
      "resource_type": "task",
      "content": "我已完成第一阶段的开发工作,请审核。",
      "created": "2024-01-01T10:00:00Z",
      "updated": "2024-01-01T15:30:00Z",
      "reply_to_comment_id": null,
      "create_user": {
        "user_id": "user_self",
        "name": "张三",
        "email": "zhangsan@example.com"
      }
    }
  },
  "msg": "success"
}

说明:给定一个评论的ID,返回个人评论的详情,包括内容,创建人,创建时间和更新时间等信息。用户只能查看自己有权限的评论详情。

代码示例

typescript
const response = await feishuUserClient.getCommentById("7198104824246747156");
const comment = response.data.comment;

console.log("个人评论详情:");
console.log(`评论ID: ${comment.comment_id}`);
console.log(`内容: ${comment.content}`);
console.log(`创建者: ${comment.create_user.name} (${comment.create_user.email})`);
console.log(`创建时间: ${comment.created}`);
console.log(`更新时间: ${comment.updated}`);
console.log(`所属任务: ${comment.resource_id}`);
console.log(`是否为回复: ${comment.reply_to_comment_id ? '是' : '否'}`);

// 分析评论的编辑情况
const createdTime = new Date(comment.created);
const updatedTime = new Date(comment.updated);
const wasEdited = updatedTime > createdTime;

if (wasEdited) {
  const editDuration = updatedTime.getTime() - createdTime.getTime();
  const editMinutes = Math.floor(editDuration / (1000 * 60));
  const editHours = Math.floor(editMinutes / 60);
  
  console.log(`评论已被编辑过:`);
  console.log(`- 编辑时间距离创建: ${editHours} 小时 ${editMinutes % 60} 分钟`);
  console.log(`- 原创建时间: ${createdTime.toLocaleString('zh-CN')}`);
  console.log(`- 最后更新: ${updatedTime.toLocaleString('zh-CN')}`);
} else {
  console.log("评论未被编辑");
}

// 检查是否为自己的评论
if (comment.create_user.user_id === "user_self") {
  console.log("这是您自己创建的评论,可以进行编辑或删除操作");
  
  // 获取评论的操作选项
  const now = new Date();
  const commentAge = now.getTime() - createdTime.getTime();
  const hoursSinceCreation = Math.floor(commentAge / (1000 * 60 * 60));
  
  console.log("可用操作:");
  console.log("- 编辑: ✓ (可编辑内容)");
  console.log("- 删除: ✓ (可永久删除)");
  console.log(`- 评论时长: ${hoursSinceCreation} 小时`);
  
  if (hoursSinceCreation > 24) {
    console.log("⚠ 注意: 评论已超过24小时,编辑前请确认内容的准确性");
  }
} else {
  console.log("这是其他用户创建的评论,您只能查看");
}

// 批量获取个人评论的详细信息
async function getPersonalCommentDetails(commentIds: string[]) {
  const commentDetails = [];
  
  for (const commentId of commentIds) {
    try {
      const response = await feishuUserClient.getCommentById(commentId);
      const comment = response.data.comment;
      
      const detail = {
        commentId: commentId,
        success: true,
        content: comment.content,
        author: comment.create_user.name,
        createdAt: comment.created,
        updatedAt: comment.updated,
        isEdited: new Date(comment.updated) > new Date(comment.created),
        isOwn: comment.create_user.user_id === "user_self",
        isReply: comment.reply_to_comment_id !== null,
        taskId: comment.resource_id
      };
      
      commentDetails.push(detail);
      
    } catch (error) {
      commentDetails.push({
        commentId: commentId,
        success: false,
        error: error.message
      });
    }
  }
  
  return commentDetails;
}

// 使用批量获取功能
const commentIds = ["comment_1", "comment_2", "comment_3"];
const details = await getPersonalCommentDetails(commentIds);

console.log("个人评论详细信息:");
details.forEach(detail => {
  if (detail.success) {
    const status = [];
    if (detail.isEdited) status.push("已编辑");
    if (detail.isOwn) status.push("自己的");
    if (detail.isReply) status.push("回复");
    
    console.log(`${detail.author}: ${detail.content}`);
    console.log(`  状态: ${status.join(", ") || "普通评论"}`);
    console.log(`  时间: ${detail.createdAt}`);
    console.log(`  任务: ${detail.taskId}`);
    console.log("");
  } else {
    console.log(`评论 ${detail.commentId} 获取失败: ${detail.error}`);
  }
});

更新评论

函数签名

csharp
Task<FeishuApiResult<CommentOpreationResult>?> UpdateCommentByIdAsync(
      [Path] string comment_id,
      [Body] UpdateCommentRequest updateCommentRequest,
      [Query("user_id_type")] string user_id_type = Consts.User_Id_Type,
      CancellationToken cancellationToken = default);

认证:用户令牌

参数

  • comment_id (string): 要更新评论详情的评论ID,示例值:"7198104824246747156"
  • updateCommentRequest (UpdateCommentRequest): 更新评论请求体
  • user_id_type (string): 用户ID类型,默认值为Consts.User_Id_Type
  • cancellationToken (CancellationToken): 取消操作令牌对象

响应

json
{
  "code": 0,
  "data": {
    "comment": {
      "comment_id": "7198104824246747156",
      "resource_id": "d300a75f-c56a-4be9-80d1-e47653028ceb",
      "resource_type": "task",
      "content": "更新后的个人评论内容",
      "created": "2024-01-01T10:00:00Z",
      "updated": "2024-01-01T16:45:00Z",
      "reply_to_comment_id": null,
      "create_user": {
        "user_id": "user_self",
        "name": "张三",
        "email": "zhangsan@example.com"
      }
    }
  },
  "msg": "success"
}

说明:更新一条个人评论。更新时,将update_fields字段中填写所有要修改的评论的字段名,同时在comment字段中填写要修改的字段的新值即可。用户只能更新自己创建的评论。

代码示例

typescript
const updateCommentRequest = {
  update_fields: ["content"],
  comment: {
    content: "更新进度:已完成90%的开发工作,正在进行最后测试,预计明日中午前完成。"
  }
};

const response = await feishuUserClient.updateCommentById(
  "7198104824246747156",
  updateCommentRequest
);

const updatedComment = response.data.comment;
console.log("个人评论更新成功:", updatedComment.content);
console.log("更新时间:", updatedComment.updated);

// 安全更新个人评论(先检查权限)
async function safeUpdatePersonalComment(commentId: string, newContent: string) {
  try {
    // 1. 获取评论详情检查权限
    const detailResponse = await feishuUserClient.getCommentById(commentId);
    const comment = detailResponse.data.comment;
    
    // 2. 检查是否为自己的评论
    if (comment.create_user.user_id !== "user_self") {
      throw new Error("无权编辑其他用户的评论");
    }
    
    // 3. 显示原内容供确认
    console.log("准备更新个人评论:");
    console.log(`原内容: ${comment.content}`);
    console.log(`新内容: ${newContent}`);
    console.log(`创建时间: ${comment.created}`);
    
    // 4. 确认更新
    const confirmed = confirm("确定要更新这条评论吗?");
    if (!confirmed) {
      console.log("用户取消了更新操作");
      return null;
    }
    
    // 5. 执行更新
    const updateRequest = {
      update_fields: ["content"],
      comment: { content: newContent }
    };
    
    const updateResponse = await feishuUserClient.updateCommentById(commentId, updateRequest);
    
    console.log("个人评论更新成功:");
    console.log(`评论ID: ${updateResponse.data.comment.comment_id}`);
    console.log(`更新时间: ${updateResponse.data.comment.updated}`);
    
    return updateResponse.data.comment;
    
  } catch (error) {
    console.error("更新个人评论失败:", error.message);
    
    // 检查具体错误类型
    if (error.message.includes("403") || error.message.includes("permission")) {
      console.log("错误原因: 没有编辑此评论的权限");
    } else if (error.message.includes("404")) {
      console.log("错误原因: 评论不存在或已被删除");
    }
    
    return null;
  }
}

// 使用安全更新功能
const safeUpdateResult = await safeUpdatePersonalComment(
  "7198104824246747156",
  "最新进展:已完成全部开发工作,正在准备测试环境,请安排测试。"
);

// 批量更新个人进度评论
async function batchUpdateProgressComments(commentIds: string[], progressTemplate: (comment: any) => string) {
  const results = [];
  
  for (const commentId of commentIds) {
    try {
      // 获取原评论
      const detailResponse = await feishuUserClient.getCommentById(commentId);
      const comment = detailResponse.data.comment;
      
      // 检查权限
      if (comment.create_user.user_id !== "user_self") {
        results.push({
          commentId: commentId,
          success: false,
          error: "无权编辑其他用户的评论"
        });
        continue;
      }
      
      // 生成新内容
      const newContent = progressTemplate(comment);
      
      // 更新评论
      const updateRequest = {
        update_fields: ["content"],
        comment: { content: newContent }
      };
      
      await feishuUserClient.updateCommentById(commentId, updateRequest);
      
      results.push({
        commentId: commentId,
        success: true,
        oldContent: comment.content,
        newContent: newContent,
        updatedAt: new Date().toISOString()
      });
      
      console.log(`评论 ${commentId} 更新成功`);
      
      // 添加延迟
      await new Promise(resolve => setTimeout(resolve, 200));
      
    } catch (error) {
      results.push({
        commentId: commentId,
        success: false,
        error: error.message
      });
      
      console.log(`评论 ${commentId} 更新失败: ${error.message}`);
    }
  }
  
  return results;
}

// 使用批量更新功能
const commentIds = ["comment_1", "comment_2"];
const batchResults = await batchUpdateProgressComments(commentIds, (comment) => {
  return `【更新 ${new Date().toLocaleDateString()}】原内容已更新,请查看最新状态。`;
});

console.log("批量更新结果:");
batchResults.forEach(result => {
  if (result.success) {
    console.log(`✓ 评论 ${result.commentId}:`);
    console.log(`  原: ${result.oldContent.substring(0, 50)}...`);
    console.log(`  新: ${result.newContent.substring(0, 50)}...`);
  } else {
    console.log(`✗ 评论 ${result.commentId}: ${result.error}`);
  }
});

删除评论

函数签名

csharp
Task<FeishuNullDataApiResult?> DeleteCommentByIdAsync(
   [Path] string comment_id,
   [Query("user_id_type")] string user_id_type = Consts.User_Id_Type,
   CancellationToken cancellationToken = default);

认证:用户令牌

参数

  • comment_id (string): 要删除评论详情的评论ID,示例值:"7198104824246747156"
  • user_id_type (string): 用户ID类型,默认值为Consts.User_Id_Type
  • cancellationToken (CancellationToken): 取消操作令牌对象

响应

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

说明:删除一条个人评论。评论被删除后,将无法进行任何操作,也无法恢复,请谨慎操作。用户只能删除自己创建的评论。

代码示例

typescript
// 安全删除个人评论:先检查权限,确认后删除
async function safeDeletePersonalComment(commentId: string) {
  try {
    // 1. 获取评论详情
    const detailResponse = await feishuUserClient.getCommentById(commentId);
    const comment = detailResponse.data.comment;
    
    // 2. 检查是否为自己的评论
    if (comment.create_user.user_id !== "user_self") {
      throw new Error("无权删除其他用户的评论");
    }
    
    // 3. 显示评论信息供确认
    console.log("准备删除个人评论:");
    console.log(`评论ID: ${comment.comment_id}`);
    console.log(`内容: ${comment.content}`);
    console.log(`创建时间: ${comment.created}`);
    console.log(`所属任务: ${comment.resource_id}`);
    
    // 检查评论是否被回复
    if (comment.reply_to_comment_id) {
      console.log(`这是回复评论,原评论ID: ${comment.reply_to_comment_id}`);
    }
    
    // 4. 确认删除
    const confirmed = confirm(`确定要删除这条个人评论吗?\n内容: ${comment.content.substring(0, 50)}...\n\n此操作不可恢复!`);
    
    if (confirmed) {
      // 5. 执行删除操作
      const deleteResponse = await feishuUserClient.deleteCommentById(commentId);
      
      if (deleteResponse.code === 0) {
        console.log(`个人评论删除成功: ${comment.comment_id}`);
        
        // 记录删除日志
        const deletionLog = {
          commentId: commentId,
          content: comment.content,
          createdAt: comment.created,
          deletedAt: new Date().toISOString(),
          taskId: comment.resource_id,
          deletionReason: "用户主动删除"
        };
        
        console.log("删除日志:", deletionLog);
        return true;
      } else {
        console.log(`删除失败: ${deleteResponse.msg}`);
        return false;
      }
    } else {
      console.log("用户取消了删除操作");
      return false;
    }
    
  } catch (error) {
    console.log(`删除个人评论失败: ${error.message}`);
    
    // 检查错误类型
    if (error.message.includes("403") || error.message.includes("permission")) {
      console.log("可能的原因: 没有删除此评论的权限");
    } else if (error.message.includes("404")) {
      console.log("可能的原因: 评论不存在或已被删除");
    }
    
    return false;
  }
}

// 使用安全删除功能
const deleteResult = await safeDeletePersonalComment("7198104824246747156");

// 批量清理个人旧评论
async function cleanupOldPersonalComments(taskId: string, daysThreshold: number = 30) {
  try {
    // 1. 获取任务的所有评论
    const commentsResponse = await feishuUserClient.getCommentPageList({
      resource_id: taskId,
      page_size: 100
    });
    
    // 2. 筛选自己的旧评论
    const thresholdDate = new Date();
    thresholdDate.setDate(thresholdDate.getDate() - daysThreshold);
    
    const oldPersonalComments = commentsResponse.data.items.filter(comment => {
      const isOwn = comment.create_user.user_id === "user_self";
      const isOld = new Date(comment.created) < thresholdDate;
      return isOwn && isOld;
    });
    
    if (oldPersonalComments.length === 0) {
      console.log(`没有找到超过 ${daysThreshold} 天的个人评论`);
      return { total: 0, deleted: 0 };
    }
    
    console.log(`找到 ${oldPersonalComments.length} 条超过 ${daysThreshold} 天的个人评论:`);
    oldPersonalComments.forEach(comment => {
      console.log(`- ${comment.content.substring(0, 40)}... (${comment.created})`);
    });
    
    // 3. 确认批量删除
    const confirmed = confirm(`确定要删除这 ${oldPersonalComments.length} 条旧评论吗?\n\n此操作不可恢复!`);
    
    if (!confirmed) {
      console.log("用户取消了批量删除操作");
      return { total: oldPersonalComments.length, deleted: 0 };
    }
    
    // 4. 执行批量删除
    let deletedCount = 0;
    for (const comment of oldPersonalComments) {
      try {
        await feishuUserClient.deleteCommentById(comment.comment_id);
        console.log(`已删除: ${comment.comment_id}`);
        deletedCount++;
        
        // 添加延迟避免请求过快
        await new Promise(resolve => setTimeout(resolve, 100));
        
      } catch (error) {
        console.log(`删除失败: ${comment.comment_id}, 错误: ${error.message}`);
      }
    }
    
    console.log(`批量删除完成: 成功删除 ${deletedCount}/${oldPersonalComments.length} 条个人评论`);
    return { total: oldPersonalComments.length, deleted: deletedCount };
    
  } catch (error) {
    console.error("清理个人旧评论失败:", error);
    return { total: 0, deleted: 0 };
  }
}

// 使用清理功能
const cleanupResult = await cleanupOldPersonalComments(
  "d300a75f-c56a-4be9-80d1-e47653028ceb", 
  30
);

console.log(`清理结果: 发现 ${cleanupResult.total} 条,删除 ${cleanupResult.deleted} 条`);

获取评论列表

函数签名

csharp
Task<FeishuApiPageListResult<TaskCommentInfo>?> GetCommentPageListAsync(
     [Query("resource_id")] string? resource_id = null,
     [Query("resource_type")] string? resource_type = "task",
     [Query("direction")] string? direction = "asc",
     [Query("page_size")] int page_size = 10,
     [Query("page_token")] string? page_token = null,
     [Query("user_id_type")] string user_id_type = Consts.User_Id_Type,
     CancellationToken cancellationToken = default);

认证:用户令牌

参数

  • resource_id (string): 要获取评论的资源ID,例如个人任务全局唯一ID,示例值:"d300a75f-c56a-4be9-80d1-e47653028ceb"
  • resource_type (string): 要获取评论列表的资源类型,目前只支持"task",默认为"task",示例值:"task"
  • direction (string): 返回数据的排序方式,"asc"表示从最老到最新顺序返回;"desc"表示从最新到最老顺序返回。默认为"asc"
  • page_size (int): 分页大小,默认值:10
  • page_token (string): 分页标记,第一次请求不填
  • user_id_type (string): 用户ID类型,默认值为Consts.User_Id_Type
  • cancellationToken (CancellationToken): 取消操作令牌对象

响应

json
{
  "code": 0,
  "data": {
    "items": [
      {
        "comment_id": "7198104824246747156",
        "resource_id": "d300a75f-c56a-4be9-80d1-e47653028ceb",
        "resource_type": "task",
        "content": "个人进度更新:已完成UI设计部分。",
        "created": "2024-01-01T10:00:00Z",
        "updated": "2024-01-01T10:00:00Z",
        "reply_to_comment_id": null,
        "create_user": {
          "user_id": "user_self",
          "name": "张三",
          "email": "zhangsan@example.com"
        }
      }
    ],
    "page_token": "next_page_token",
    "has_more": true
  },
  "msg": "success"
}

说明:给定一个资源,返回该资源的个人评论列表。支持分页。评论可以按照创建时间的正序(asc, 从最老到最新),或者逆序(desc,从最老到最新),返回数据。用户只能查看自己有权限的评论列表。

代码示例

typescript
// 获取个人任务的所有评论(按时间正序)
const response = await feishuUserClient.getCommentPageList({
  resource_id: "d300a75f-c56a-4be9-80d1-e47653028ceb",
  resource_type: "task",
  direction: "asc",
  page_size: 20
});

const comments = response.data.items;
console.log(`获取到 ${comments.length} 条评论:`);

comments.forEach((comment, index) => {
  const isOwn = comment.create_user.user_id === "user_self";
  const isEdited = new Date(comment.updated) > new Date(comment.created);
  const isReply = comment.reply_to_comment_id !== null;
  
  const badges = [];
  if (isOwn) badges.push("自己");
  if (isEdited) badges.push("已编辑");
  if (isReply) badges.push("回复");
  
  const badgeText = badges.length > 0 ? ` [${badges.join(", ")}]` : "";
  
  console.log(`${index + 1}. ${comment.create_user.name}${badgeText}: ${comment.content}`);
  console.log(`   时间: ${comment.created}`);
  if (isReply) {
    console.log(`   回复: ${comment.reply_to_comment_id}`);
  }
  console.log("");
});

// 分页获取所有评论
async function getAllPersonalComments(taskId: string, direction: string = "asc") {
  let pageToken: string | undefined = undefined;
  let allComments = [];
  let pageCount = 0;
  
  do {
    pageCount++;
    console.log(`正在获取第 ${pageCount} 页评论...`);
    
    const pageResponse = await feishuUserClient.getCommentPageList({
      resource_id: taskId,
      resource_type: "task",
      direction: direction,
      page_size: 50,
      page_token: pageToken
    });
    
    allComments.push(...pageResponse.data.items);
    pageToken = pageResponse.data.page_token;
    
    console.log(`第 ${pageCount} 页获取到 ${pageResponse.data.items.length} 条评论,总计 ${allComments.length} 条`);
  } while (pageToken);
  
  return allComments;
}

// 个人评论统计分析
async function analyzePersonalComments(taskId: string) {
  const allComments = await getAllPersonalComments(taskId);
  
  if (allComments.length === 0) {
    console.log("该任务暂无评论");
    return null;
  }
  
  // 筛选自己的评论
  const personalComments = allComments.filter(comment => comment.create_user.user_id === "user_self");
  const otherComments = allComments.filter(comment => comment.create_user.user_id !== "user_self");
  
  // 基础统计
  const analysis = {
    totalComments: allComments.length,
    personalComments: personalComments.length,
    otherComments: otherComments.length,
    dateRange: {
      earliest: new Date(Math.min(...allComments.map(c => new Date(c.created).getTime()))),
      latest: new Date(Math.max(...allComments.map(c => new Date(c.created).getTime())))
    },
    replies: allComments.filter(c => c.reply_to_comment_id !== null).length,
    personalReplies: personalComments.filter(c => c.reply_to_comment_id !== null).length,
    editedPersonalComments: personalComments.filter(c => new Date(c.updated) > new Date(c.created)).length
  };
  
  // 按日期统计个人评论
  const personalDateStats = personalComments.reduce((acc, comment) => {
    const date = new Date(comment.created).toLocaleDateString();
    acc[date] = (acc[date] || 0) + 1;
    return acc;
  }, {});
  
  // 最近活动
  const recentThreshold = new Date();
  recentThreshold.setHours(recentThreshold.getHours() - 24);
  const recentPersonalComments = personalComments.filter(
    comment => new Date(comment.created) > recentThreshold
  );
  
  console.log("个人评论分析结果:");
  console.log(`总评论数: ${analysis.totalComments}`);
  console.log(`个人评论数: ${analysis.personalComments} (${((analysis.personalComments / analysis.totalComments) * 100).toFixed(1)}%)`);
  console.log(`他人评论数: ${analysis.otherComments}`);
  console.log(`时间范围: ${analysis.dateRange.earliest.toLocaleDateString()} 至 ${analysis.dateRange.latest.toLocaleDateString()}`);
  console.log(`回复评论数: ${analysis.replies} (个人回复: ${analysis.personalReplies})`);
  console.log(`编辑过的个人评论数: ${analysis.editedPersonalComments}`);
  console.log(`最近24小时个人评论: ${recentPersonalComments.length}`);
  
  console.log("\n个人评论按日期统计:");
  Object.entries(personalDateStats).forEach(([date, count]) => {
    console.log(`${date}: ${count} 条个人评论`);
  });
  
  return {
    analysis: analysis,
    personalComments: personalComments,
    personalDateStats: personalDateStats,
    recentActivity: recentPersonalComments
  };
}

// 使用分析功能
const personalCommentAnalysis = await analyzePersonalComments("d300a75f-c56a-4be9-80d1-e47653028ceb");

// 查找可编辑的个人评论
if (personalCommentAnalysis) {
  const editableComments = personalCommentAnalysis.personalComments.filter(comment => {
    // 可以编辑自己的评论
    return comment.create_user.user_id === "user_self";
  });
  
  console.log(`\n可编辑的个人评论: ${editableComments.length} 条`);
  editableComments.forEach(comment => {
    const timeAgo = getTimeAgo(new Date(comment.created));
    console.log(`- ${comment.comment_id}: ${comment.content.substring(0, 30)}... (${timeAgo})`);
  });
}

// 辅助函数:计算时间差
function getTimeAgo(date: Date): string {
  const now = new Date();
  const diffInMinutes = Math.floor((now.getTime() - date.getTime()) / (1000 * 60));
  
  if (diffInMinutes < 60) {
    return `${diffInMinutes} 分钟前`;
  } else if (diffInMinutes < 1440) {
    return `${Math.floor(diffInMinutes / 60)} 小时前`;
  } else {
    return `${Math.floor(diffInMinutes / 1440)} 天前`;
  }
}

// 获取特定用户的评论(包括自己和他人的)
function getCommentsByUser(comments: any[], userName: string) {
  return comments.filter(comment => 
    comment.create_user.name.toLowerCase().includes(userName.toLowerCase())
  );
}

// 查找包含关键词的评论
function findCommentsByKeyword(comments: any[], keyword: string) {
  return comments.filter(comment => 
    comment.content.toLowerCase().includes(keyword.toLowerCase())
  );
}

// 使用查找功能
if (personalCommentAnalysis) {
  // 查找自己的评论
  const myComments = getCommentsByUser(personalCommentAnalysis.personalComments, "张三");
  console.log(`\n自己的评论: ${myComments.length} 条`);
  
  // 查找包含"进度"的评论
  const progressComments = findCommentsByKeyword(personalCommentAnalysis.personalComments, "进度");
  console.log(`包含"进度"的个人评论: ${progressComments.length} 条`);
  progressComments.forEach(comment => {
    console.log(`- ${comment.content} (${comment.created})`);
  });
}

个人评论管理最佳实践

个人评论管理器类

typescript
class PersonalCommentManager {
  private userClient: any;
  
  constructor(userClient: any) {
    this.userClient = userClient;
  }
  
  // 创建带状态标签的评论
  async createStatusComment(taskId: string, status: string, details?: string) {
    const statusLabels = {
      '开始': '🚀',
      '进行中': '⏳', 
      '完成': '✅',
      '暂停': '⏸️',
      '问题': '❌',
      '更新': '🔄'
    };
    
    const emoji = statusLabels[status] || '📝';
    const timestamp = new Date().toLocaleString('zh-CN');
    const content = details 
      ? `${emoji} 【${status}】${details}\n⏰ ${timestamp}`
      : `${emoji} 【${status}】\n⏰ ${timestamp}`;
    
    const request = {
      resource_id: taskId,
      resource_type: "task",
      content: content
    };
    
    const response = await this.userClient.createComment(request);
    console.log(`状态评论创建成功: ${status}`);
    return response.data.comment;
  }
  
  // 获取个人评论摘要
  async getPersonalCommentSummary(taskId: string) {
    const allComments = await this.getAllComments(taskId);
    const personalComments = allComments.filter(c => c.create_user.user_id === "user_self");
    
    const summary = {
      totalPersonalComments: personalComments.length,
      recentActivity: personalComments.filter(c => {
        const hoursAgo = (Date.now() - new Date(c.created).getTime()) / (1000 * 60 * 60);
        return hoursAgo <= 24;
      }).length,
      editedCount: personalComments.filter(c => 
        new Date(c.updated) > new Date(c.created)
      ).length,
      replyCount: personalComments.filter(c => c.reply_to_comment_id !== null).length
    };
    
    return summary;
  }
  
  // 批量更新个人评论模板
  async batchUpdateWithTemplate(commentIds: string[], template: string, variables?: Record<string, any>) {
    const results = [];
    
    for (const commentId of commentIds) {
      try {
        // 检查权限
        const detailResponse = await this.userClient.getCommentById(commentId);
        const comment = detailResponse.data.comment;
        
        if (comment.create_user.user_id !== "user_self") {
          results.push({
            commentId,
            success: false,
            error: "无权编辑其他用户的评论"
          });
          continue;
        }
        
        // 应用模板
        let newContent = template;
        if (variables) {
          Object.keys(variables).forEach(key => {
            newContent = newContent.replace(new RegExp(`\\{${key}\\}`, 'g'), variables[key]);
          });
        }
        
        // 添加时间戳
        const timestamp = new Date().toLocaleString('zh-CN');
        newContent += `\n\n📝 更新时间: ${timestamp}`;
        
        // 执行更新
        const updateRequest = {
          update_fields: ["content"],
          comment: { content: newContent }
        };
        
        await this.userClient.updateCommentById(commentId, updateRequest);
        
        results.push({
          commentId,
          success: true,
          oldContent: comment.content,
          newContent: newContent
        });
        
      } catch (error) {
        results.push({
          commentId,
          success: false,
          error: error.message
        });
      }
    }
    
    return results;
  }
  
  // 获取所有评论
  private async getAllComments(taskId: string) {
    let pageToken: string | undefined = undefined;
    let allComments = [];
    
    do {
      const response = await this.userClient.getCommentPageList({
        resource_id: taskId,
        page_size: 100,
        page_token: pageToken
      });
      
      allComments.push(...response.data.items);
      pageToken = response.data.page_token;
    } while (pageToken);
    
    return allComments;
  }
}

// 使用个人评论管理器
const personalCommentManager = new PersonalCommentManager(feishuUserClient);

// 创建不同类型的评论
const statusComment = await personalCommentManager.createStatusComment(
  "task_123", 
  "进行中", 
  "已完成前端开发,正在进行接口联调。"
);

const problemComment = await personalCommentManager.createStatusComment(
  "task_123", 
  "问题", 
  "接口返回数据格式与预期不符,需要后端配合调整。"
);

// 获取个人评论摘要
const summary = await personalCommentManager.getPersonalCommentSummary("task_123");
console.log("个人评论摘要:", summary);

// 批量更新评论(使用模板)
const templateResult = await personalCommentManager.batchUpdateWithTemplate(
  ["comment_1", "comment_2"],
  "【模板更新】{status}\n原内容: {original}\n新进度: {progress}",
  {
    status: "进度更新",
    progress: "已完成80%"
  }
);

console.log("批量更新结果:", templateResult);

// 个人评论工作流
async function personalCommentWorkflow(taskId: string) {
  console.log("开始个人评论工作流...");
  
  // 1. 创建开始评论
  await personalCommentManager.createStatusComment(taskId, "开始", "开始处理任务。");
  
  // 2. 模拟工作过程(实际应用中这里会是真实的工作)
  console.log("工作中...");
  await new Promise(resolve => setTimeout(resolve, 2000));
  
  // 3. 创建进行中评论
  await personalCommentManager.createStatusComment(taskId, "进行中", "已完成50%的工作内容。");
  
  // 4. 模拟完成工作
  console.log("继续工作中...");
  await new Promise(resolve => setTimeout(resolve, 2000));
  
  // 5. 创建完成评论
  await personalCommentManager.createStatusComment(taskId, "完成", "任务已全部完成,请审核。");
  
  // 6. 获取最终摘要
  const finalSummary = await personalCommentManager.getPersonalCommentSummary(taskId);
  console.log("工作流完成,最终评论摘要:", finalSummary);
}

// 运行工作流
// await personalCommentWorkflow("task_123");