fix: 修复审批详情显示实际审批人和飞书消息emoji编码

1. 审批详情显示修复
   - 新增 ApprovalService::getDetail() 方法
   - 从 form_data 获取用户实际选择的审批人和抄送人
   - 返回每个节点的 actual_approvers 和 approver_statuses
   - 修复详情页显示默认审批人而非实际审批人的问题

2. 飞书消息emoji编码修复
   - 修复 content 字段格式:应为 card 对象JSON字符串,不是 {"card":{...}}
   - 使用 JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
   - 新增 HttpClient::httpPostJson() 方法处理预编码字段
   - 修复消息发送错误码 200621

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-03-01 10:02:53 +08:00
parent 8403d24be3
commit 3ebbbefb8d
4 changed files with 209 additions and 12 deletions
@@ -566,13 +566,19 @@ class FeishuNotificationService
error_log('📤 发送飞书消息: app_id=' . $app['app_id'] . ', feishu_user_id=' . $feishuUserId);
error_log('📦 消息卡片: ' . json_encode($card, JSON_UNESCAPED_UNICODE));
$response = HttpClient::httpPost(
// content 必须是 card 对象的 JSON 字符串,不是 {"card":{...}}
// JSON_UNESCAPED_UNICODE 保留 emoji
// JSON_UNESCAPED_SLASHES 避免 URL 中的 / 被转义为 \/
$contentJson = json_encode($card, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$response = HttpClient::httpPostJson(
"https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id",
[
'receive_id' => $feishuUserId,
'msg_type' => 'interactive',
'content' => ['card' => $card], // 直接传递数组,让 HttpClient 进行编码
'content' => $contentJson,
],
['content'], // content 字段是预编码的 JSON 字符串
[
'Authorization: Bearer ' . $token,
]
@@ -707,13 +713,18 @@ class FeishuNotificationService
'operator' => $operatorName,
];
$response = HttpClient::httpPost(
// content 必须是 card 对象的 JSON 字符串,不是 {"card":{...}}
// JSON_UNESCAPED_UNICODE 保留 emoji
// JSON_UNESCAPED_SLASHES 避免 URL 中的 / 被转义为 \/
$contentJson = json_encode($updatedCard, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
$response = HttpClient::httpPostJson(
"https://open.feishu.cn/open-apis/im/v1/messages/{$message->message_id}/update",
[
'msg_type' => 'interactive',
// 直接传递数组,让 HttpClient 进行编码
'content' => ['card' => $updatedCard],
'content' => $contentJson,
],
['content'], // content 字段是预编码的 JSON 字符串
[
'Authorization: Bearer ' . $token,
]
@@ -826,15 +837,18 @@ class FeishuNotificationService
$apiUrl = "https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type=user_id";
// content 必须是 JSON 字符串,使用 httpPostJson 避免二次编码
$contentJson = json_encode(['text' => $text], JSON_UNESCAPED_UNICODE);
$requestData = [
'receive_id' => $feishuUserId,
'msg_type' => 'text',
'content' => json_encode(['text' => $text]),
'content' => $contentJson,
];
error_log('📤 发送文本消息: feishu_user_id=' . $feishuUserId . ', text=' . substr($text, 0, 100));
$responseData = \app\util\HttpClient::httpPost($apiUrl, $requestData, [
$responseData = \app\util\HttpClient::httpPostJson($apiUrl, $requestData, ['content'], [
'Authorization: Bearer ' . $accessToken,
]);