feat: 接入飞书消息通知到出差审批功能

- 提交申请后通知审批人和抄送人
- 审批通过/拒绝后通知申请人
- 取消申请后通知审批人和抄送人
- 新增 sendApprovalNotification() 方法
- 新增 sendApprovalResultNotification() 方法
- 新增 sendCancelNotification() 方法

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-02-26 17:16:23 +08:00
parent a88944b5e1
commit c1016c740d
+140
View File
@@ -269,10 +269,102 @@ class BusinessTripService
}
}
// 发送飞书通知给审批人
$this->sendApprovalNotification($businessTrip, $approverIds, $ccUserIds);
return $businessTrip->fresh(['itineraries', 'approvalOrder']);
});
}
/**
* 发送审批通知(飞书消息)
*/
private function sendApprovalNotification(BusinessTrip $businessTrip, array $approverIds, array $ccUserIds): void
{
try {
$notificationService = new \app\service\FeishuNotificationService();
// 构建详情链接
$detailUrl = "https://xsm.dev.hnxinyouhe.com/business-trip/detail/{$businessTrip->id}";
// 构建内容
$content = "**出差原因**: {$businessTrip->reason}\n";
$content .= "**目的地**: {$businessTrip->destination}\n";
$content .= "**时间**: {$businessTrip->start_date} 至 {$businessTrip->end_date}";
// 通知审批人
foreach ($approverIds as $approverId) {
try {
$notificationService->setAppByUser($approverId)
->sendApprovalNotification([
'user_id' => $approverId,
'title' => '新的出差审批申请',
'applicant' => $businessTrip->user->name,
'type' => '出差申请',
'content' => $content,
'url' => $detailUrl,
]);
} catch (\Exception $e) {
error_log("发送审批通知失败: approver_id={$approverId}, error=" . $e->getMessage());
}
}
// 通知抄送人
foreach ($ccUserIds as $ccUserId) {
try {
$notificationService->setAppByUser($ccUserId)
->sendSystemNotification([
'user_ids' => [$ccUserId],
'title' => '出差申请抄送',
'content' => "**申请人**: {$businessTrip->user->name}\n" . $content,
'url' => $detailUrl,
]);
} catch (\Exception $e) {
error_log("发送抄送通知失败: cc_user_id={$ccUserId}, error=" . $e->getMessage());
}
}
} catch (\Exception $e) {
error_log("发送飞书通知异常: " . $e->getMessage());
}
}
/**
* 发送审批结果通知(飞书消息)
*/
private function sendApprovalResultNotification(BusinessTrip $businessTrip, string $action, string $comment = ''): void
{
try {
$notificationService = new \app\service\FeishuNotificationService();
$detailUrl = "https://xsm.dev.hnxinyouhe.com/business-trip/detail/{$businessTrip->id}";
if ($action === 'approve') {
$title = '出差申请已通过';
$content = "您的出差申请已通过审批。\n";
$content .= "**申请原因**: {$businessTrip->reason}\n";
if ($comment) {
$content .= "**审批意见**: {$comment}";
}
} else {
$title = '出差申请已拒绝';
$content = "您的出差申请被拒绝。\n";
$content .= "**申请原因**: {$businessTrip->reason}\n";
if ($comment) {
$content .= "**拒绝原因**: {$comment}";
}
}
$notificationService->setAppByUser($businessTrip->user_id)
->sendSystemNotification([
'user_ids' => [$businessTrip->user_id],
'title' => $title,
'content' => $content,
'url' => $detailUrl,
]);
} catch (\Exception $e) {
error_log("发送审批结果通知失败: " . $e->getMessage());
}
}
/**
* 获取出差申请列表
*/
@@ -463,12 +555,57 @@ class BusinessTripService
$approvalOrder->status = ApprovalOrder::STATUS_CANCELLED;
$approvalOrder->current_nodes = [];
$approvalOrder->save();
// 发送取消通知给审批人和抄送人
$this->sendCancelNotification($businessTrip, $approvalOrder);
}
}
return $businessTrip->fresh();
}
/**
* 发送取消通知(飞书消息)
*/
private function sendCancelNotification(BusinessTrip $businessTrip, ApprovalOrder $approvalOrder): void
{
try {
$notificationService = new \app\service\FeishuNotificationService();
$detailUrl = "https://xsm.dev.hnxinyouhe.com/business-trip/detail/{$businessTrip->id}";
// 获取审批人和抄送人
$formData = $approvalOrder->form_data ?? [];
$approvers = $formData['approvers'] ?? [];
$ccUsers = $formData['cc_users'] ?? [];
$content = "**申请人**: {$businessTrip->user->name}\n";
$content .= "**出差原因**: {$businessTrip->reason}\n";
$content .= "**目的地**: {$businessTrip->destination}";
// 合并所有需要通知的用户ID
$allUserIds = array_unique(array_merge(
array_column($approvers, 'id'),
array_column($ccUsers, 'id')
));
foreach ($allUserIds as $notifyUserId) {
try {
$notificationService->setAppByUser($notifyUserId)
->sendSystemNotification([
'user_ids' => [$notifyUserId],
'title' => '出差申请已取消',
'content' => $content,
'url' => $detailUrl,
]);
} catch (\Exception $e) {
error_log("发送取消通知失败: user_id={$notifyUserId}, error=" . $e->getMessage());
}
}
} catch (\Exception $e) {
error_log("发送取消通知异常: " . $e->getMessage());
}
}
/**
* 删除草稿
*/
@@ -572,6 +709,9 @@ class BusinessTripService
$approvalOrder->save();
$businessTrip->save();
// 发送审批结果通知
$this->sendApprovalResultNotification($businessTrip, $action, $comment);
return $businessTrip->fresh(['itineraries', 'approvalOrder']);
});
}