diff --git a/src/app/api/controller/Kefu.php b/src/app/api/controller/Kefu.php index 3b6d17bf3..f955222a8 100644 --- a/src/app/api/controller/Kefu.php +++ b/src/app/api/controller/Kefu.php @@ -10,6 +10,127 @@ use think\facade\Event; */ class Kefu extends BaseApi { + /** + * 系统健康检查, 用来检测当前的AI服务是否正常 + * @return \think\response\Json | bool + */ + public function health() + { + $start_time = microtime(true); + + // (必选) 获取站点ID和会员ID,可以通过事件数据传递 + $site_id = $this->params['uniacid'] ?? $this->site_id; // 使用 uniacid, 方便以后迁移,而且uniacid 是唯一的, site_id 不是,同时被params给过滤了 + + // 检查site_id 如果 < 1, 则返回错误 + if ($site_id < 1) { + return $this->response($this->error('缺少关键参数站点ID')); + } + + // 准备事件数据 + $event_data = [ + 'check_id' => uniqid('health_', true), + 'timestamp' => date('Y-m-d H:i:s'), + 'site_id' => $site_id, + 'check_type' => $this->params['check_type'] ?? 'full' // full, basic, ai_service + ]; + + $health_summary = null; + $event_data = [ + 'check_id' => uniqid('health_', true), + 'timestamp' => date('Y-m-d H:i:s'), + 'site_id' => $site_id, + 'check_type' => $this->params['check_type'] ?? 'full' // full, basic, ai_service + ]; + + try { + // 触发健康检查事件 + $result = Event::trigger('KefuHealthCheck', $event_data); + + // 汇总检查结果 + $health_summary = [ + 'status' => 'healthy', + 'check_id' => $event_data['check_id'], + 'timestamp' => $event_data['timestamp'], + 'total_checks' => 0, + 'passed_checks' => 0, + 'failed_checks' => 0, + 'response_time_ms' => 0, + 'components' => [], + 'warnings' => [], + 'errors' => [] + ]; + + if (is_array($result) && !empty($result)) { + foreach ($result as $check_result) { + if (isset($check_result['component'])) { + $health_summary['components'][$check_result['component']] = $check_result; + $health_summary['total_checks']++; + + if ($check_result['status'] === 'healthy') { + $health_summary['passed_checks']++; + } else { + $health_summary['failed_checks']++; + if ($check_result['status'] === 'error') { + $health_summary['errors'][] = $check_result['message'] ?? 'Unknown error'; + $health_summary['status'] = 'unhealthy'; + } elseif ($check_result['status'] === 'warning') { + $health_summary['warnings'][] = $check_result['message'] ?? 'Unknown warning'; + if ($health_summary['status'] === 'healthy') { + $health_summary['status'] = 'warning'; + } + } + } + } + } + } + + // 计算总体响应时间 + $health_summary['response_time_ms'] = round((microtime(true) - $start_time) * 1000, 2); + + // 如果没有任何检查结果,进行基础检查 + if ($health_summary['total_checks'] === 0) { + $health_summary['components']['basic'] = [ + 'status' => 'healthy', + 'message' => '基础服务正常', + 'response_time_ms' => 0, + 'details' => [ + 'php_version' => PHP_VERSION, + 'memory_usage' => round(memory_get_usage() / 1024 / 1024, 2) . ' MB', + 'time_limit' => ini_get('max_execution_time') . 's' + ] + ]; + $health_summary['total_checks'] = 1; + $health_summary['passed_checks'] = 1; + } + + // 根据检查结果确定HTTP状态码 + $http_code = 200; + if ($health_summary['status'] === 'unhealthy') { + $http_code = 503; // Service Unavailable + } elseif ($health_summary['status'] === 'warning') { + $http_code = 200; // Still OK but with warnings + } + + return $this->response([ + 'code' => 0, + 'message' => $health_summary['status'], + 'data' => $health_summary + ], $http_code); + + } catch (\Exception $e) { + return $this->response([ + 'code' => -1, + 'message' => '健康检查失败', + 'data' => [ + 'status' => 'error', + 'check_id' => $event_data['check_id'] ?? '', + 'timestamp' => $event_data['timestamp'] ?? date('Y-m-d H:i:s'), + 'error' => $e->getMessage(), + 'response_time_ms' => round((microtime(true) - $start_time) * 1000, 2) + ] + ], 500); + } + } /** * 智能客服聊天接口 * @return \think\response\Json @@ -140,9 +261,9 @@ class Kefu extends BaseApi $member_id = $this->params['member_id'] ?? $this->member_id; $token = $this->params['token'] ?? $this->token; - // 验证参数 - if (empty($conversation_id)) { - return $this->response($this->error('会话ID不能为空')); + // 验证参数(conversation_id 和 user_id 至少需要一个) + if (empty($conversation_id) && empty($user_id)) { + return $this->response($this->error('会话ID或用户ID不能为空')); } try {