column('id', 'ID')->sortable(); $grid->column('name', '服务名称')->sortable(); $grid->column('code', '服务代码')->sortable(); // 服务类型 $grid->column('type', '服务类型')->display(function ($type) { $serviceType = SERVICE_TYPE::tryFrom($type); if ($serviceType) { $label = $serviceType->getLabel(); $color = $serviceType->getColor(); return "{$label}"; } return $type; }); // 服务提供商 $grid->column('provider', '服务提供商')->sortable(); // 认证类型 $grid->column('auth_type', '认证类型')->display(function ($authType) { $auth = AUTH_TYPE::tryFrom($authType); if ($auth) { $label = $auth->getLabel(); $level = $auth->getSecurityLevel(); $color = $auth->getSecurityLevelColor(); return "{$label}"; } return $authType; }); // 服务状态 $grid->column('status', '状态')->display(function ($status) { $serviceStatus = SERVICE_STATUS::tryFrom($status); if ($serviceStatus) { $label = $serviceStatus->getLabel(); $color = $serviceStatus->getColor(); $icon = $serviceStatus->getIcon(); return " {$label}"; } return $status; }); // 优先级 $grid->column('priority', '优先级')->sortable(); // 健康状态 $grid->column('health_status', '健康状态')->display(function ($healthStatus) { $colors = [ 'HEALTHY' => 'success', 'WARNING' => 'warning', 'ERROR' => 'danger', 'UNKNOWN' => 'secondary', ]; $color = $colors[$healthStatus] ?? 'secondary'; return "{$healthStatus}"; }); // 最后健康检查时间 $grid->column('last_health_check', '最后检查')->display(function ($time) { return $time ? $time : '未检查'; }); // 创建时间 $grid->column('created_at', '创建时间')->sortable(); // 过滤器 $grid->filter(function (Grid\Filter $filter) { $filter->equal('type', '服务类型')->select(SERVICE_TYPE::getOptions()); $filter->equal('status', '状态')->select(SERVICE_STATUS::getOptions()); $filter->equal('auth_type', '认证类型')->select(AUTH_TYPE::getOptions()); $filter->like('name', '服务名称'); $filter->like('code', '服务代码'); $filter->like('provider', '服务提供商'); }); // 批量操作 $grid->batchActions(function (Grid\Tools\BatchActions $batch) { // TODO: 创建批量操作类 // $batch->add('批量激活', new \App\Module\ThirdParty\AdminActions\BatchActivateServiceAction()); // $batch->add('批量停用', new \App\Module\ThirdParty\AdminActions\BatchDeactivateServiceAction()); }); // 工具栏 $grid->tools(function (Grid\Tools $tools) { $tools->append(' 健康检查'); $tools->append(' 统计报告'); }); // 行操作 $grid->actions(function (Grid\Displayers\Actions $actions) { $actions->append(' 凭证'); $actions->append(' 日志'); if ($actions->row->status === SERVICE_STATUS::ACTIVE->value) { $actions->append(' 测试'); } }); // 默认排序 $grid->model()->orderBy('priority')->orderBy('name'); }); } /** * 详情页面 * * @return Show */ protected function detail($id): Show { return Show::make($id, new ThirdPartyServiceRepository(), function (Show $show) { $show->field('id', 'ID'); $show->field('name', '服务名称'); $show->field('code', '服务代码'); $show->field('type', '服务类型')->as(function ($type) { $serviceType = SERVICE_TYPE::tryFrom($type); return $serviceType ? $serviceType->getLabel() : $type; }); $show->field('provider', '服务提供商'); $show->field('description', '服务描述'); $show->field('base_url', '基础URL'); $show->field('version', 'API版本'); $show->field('auth_type', '认证类型')->as(function ($authType) { $auth = AUTH_TYPE::tryFrom($authType); return $auth ? $auth->getLabel() : $authType; }); $show->field('status', '状态')->as(function ($status) { $serviceStatus = SERVICE_STATUS::tryFrom($status); return $serviceStatus ? $serviceStatus->getLabel() : $status; }); $show->field('priority', '优先级'); $show->field('timeout', '超时时间')->as(function ($timeout) { return $timeout . ' 秒'; }); $show->field('retry_times', '重试次数'); $show->field('retry_delay', '重试延迟')->as(function ($delay) { return $delay . ' 毫秒'; }); $show->field('config', '服务配置')->json(); $show->field('headers', '默认请求头')->json(); $show->field('params', '默认参数')->json(); $show->field('webhook_url', 'Webhook URL'); $show->field('health_check_url', '健康检查URL'); $show->field('health_check_interval', '健康检查间隔')->as(function ($interval) { return $interval . ' 秒'; }); $show->field('health_status', '健康状态'); $show->field('last_health_check', '最后健康检查时间'); $show->field('created_at', '创建时间'); $show->field('updated_at', '更新时间'); // 关联信息 $show->relation('credentials', '认证凭证', function ($model) { $grid = new Grid(new \App\Module\ThirdParty\Models\ThirdPartyCredential()); $grid->model()->where('service_id', $model->id); $grid->column('name', '凭证名称'); $grid->column('type', '认证类型'); $grid->column('environment', '环境'); $grid->column('is_active', '状态')->display(function ($active) { return $active ? '激活' : '未激活'; }); $grid->column('expires_at', '过期时间'); $grid->disableCreateButton(); $grid->disableActions(); return $grid; }); }); } /** * 表单页面 * * @return Form */ protected function form(): Form { return Form::make(new ThirdPartyServiceRepository(), function (Form $form) { $form->display('id', 'ID'); $form->text('name', '服务名称')->required()->help('第三方服务的显示名称'); $form->text('code', '服务代码')->help('唯一标识符,留空自动生成'); $form->select('type', '服务类型')->options(SERVICE_TYPE::getOptions())->required(); $form->text('provider', '服务提供商')->required(); $form->textarea('description', '服务描述'); $form->url('base_url', '基础URL')->help('第三方服务的API基础地址'); $form->text('version', 'API版本')->default('v1'); $form->select('auth_type', '认证类型')->options(AUTH_TYPE::getOptions())->required(); $form->select('status', '状态')->options(SERVICE_STATUS::getOptions())->default(SERVICE_STATUS::INACTIVE->value); $form->number('priority', '优先级')->default(0)->help('数字越小优先级越高'); $form->number('timeout', '超时时间(秒)')->default(30)->min(1)->max(300); $form->number('retry_times', '重试次数')->default(3)->min(0)->max(10); $form->number('retry_delay', '重试延迟(毫秒)')->default(1000)->min(100)->max(60000); $form->keyValue('config', '服务配置') ->help('服务特定配置,键值对形式输入') ->default([]); $form->keyValue('headers', '默认请求头') ->help('默认HTTP请求头,键值对形式输入') ->default([]); $form->keyValue('params', '默认参数') ->help('默认请求参数,键值对形式输入') ->default([]); $form->url('webhook_url', 'Webhook URL')->help('接收第三方服务回调的地址'); $form->text('webhook_secret', 'Webhook密钥')->help('用于验证Webhook请求的密钥'); $form->url('health_check_url', '健康检查URL')->help('用于检查服务健康状态的URL'); $form->number('health_check_interval', '健康检查间隔(秒)')->default(300)->min(60)->max(86400); $form->display('created_at', '创建时间'); $form->display('updated_at', '更新时间'); // 保存前处理 $form->saving(function (Form $form) { // 处理keyValue字段,转换为JSON存储 $keyValueFields = ['config', 'headers', 'params']; foreach ($keyValueFields as $field) { if (isset($form->$field)) { if (is_array($form->$field) && !empty($form->$field)) { // 过滤空值 $filtered = array_filter($form->$field, function($value, $key) { return !empty($key) && $value !== null && $value !== ''; }, ARRAY_FILTER_USE_BOTH); // 转换为JSON存储 $form->$field = !empty($filtered) ? json_encode($filtered, JSON_UNESCAPED_UNICODE) : null; } else { $form->$field = null; } } } }); }); } /** * 综合报告页面 * * @param Content $content * @return Content */ #[Get('reports/overview')] public function overview(Content $content) { return $content ->title('第三方服务综合报告') ->description('查看第三方服务的整体运行状况和统计数据') ->body(function (Row $row) { $row->column(12, function (Column $column) { $column->row(new ServiceOverviewCard()); }); $row->column(6, function (Column $column) { $column->row($this->buildQuickActionsCard()); }); $row->column(6, function (Column $column) { $column->row($this->buildRecentLogsCard()); }); }); } /** * 测试页面 - 改为API接口 * * @return \Illuminate\Http\JsonResponse */ #[Get('test')] public function test() { return response()->json([ 'success' => true, 'message' => 'ThirdParty模块测试接口', 'data' => [ 'module' => 'ThirdParty', 'version' => '1.0.0', 'status' => 'active', 'timestamp' => now()->toISOString(), ] ]); } /** * 健康检查API接口 * * @return \Illuminate\Http\JsonResponse */ #[Get('health-check')] public function healthCheck() { // 获取所有服务的健康状态 $services = ThirdPartyService::with(['credentials', 'quotas']) ->orderBy('priority') ->get() ->map(function ($service) { return [ 'id' => $service->id, 'name' => $service->name, 'status' => $service->status, 'health_status' => $service->health_status, 'last_health_check' => $service->last_health_check?->toISOString(), 'credentials_count' => $service->credentials->count(), 'quotas_count' => $service->quotas->count(), ]; }); return response()->json([ 'success' => true, 'message' => '服务健康检查数据', 'data' => $services ]); } /** * 统计报告API接口 * * @return \Illuminate\Http\JsonResponse */ #[Get('stats')] public function stats() { // 获取统计数据 $stats = $this->getServiceStats(); return response()->json([ 'success' => true, 'message' => '服务统计报告数据', 'data' => $stats ]); } /** * 健康报告API接口 * * @return \Illuminate\Http\JsonResponse */ #[Get('reports/health')] public function healthReport() { // 获取健康状态统计 $healthStats = $this->getHealthStats(); return response()->json([ 'success' => true, 'message' => '服务健康报告数据', 'data' => $healthStats ]); } /** * 使用统计报告API接口 * * @return \Illuminate\Http\JsonResponse */ #[Get('reports/usage')] public function usageReport() { // 获取使用统计数据 $usageStats = $this->getUsageStats(); return response()->json([ 'success' => true, 'message' => '服务使用统计报告数据', 'data' => $usageStats ]); } /** * 获取综合报告统计数据 * * @return array */ protected function getOverviewStats(): array { $totalServices = ThirdPartyService::count(); $activeServices = ThirdPartyService::where('status', SERVICE_STATUS::ACTIVE->value)->count(); $healthyServices = ThirdPartyService::where('health_status', 'HEALTHY')->count(); $totalCredentials = \App\Module\ThirdParty\Models\ThirdPartyCredential::count(); $activeCredentials = \App\Module\ThirdParty\Models\ThirdPartyCredential::where('is_active', true)->count(); $totalLogs = \App\Module\ThirdParty\Models\ThirdPartyLog::count(); $todayLogs = \App\Module\ThirdParty\Models\ThirdPartyLog::whereDate('created_at', today())->count(); $errorLogs = \App\Module\ThirdParty\Models\ThirdPartyLog::where('level', 'ERROR')->count(); return [ 'services' => [ 'total' => $totalServices, 'active' => $activeServices, 'healthy' => $healthyServices, 'inactive' => $totalServices - $activeServices, 'unhealthy' => $totalServices - $healthyServices, ], 'credentials' => [ 'total' => $totalCredentials, 'active' => $activeCredentials, 'inactive' => $totalCredentials - $activeCredentials, ], 'logs' => [ 'total' => $totalLogs, 'today' => $todayLogs, 'errors' => $errorLogs, ], ]; } /** * 获取服务统计数据 * * @return array */ protected function getServiceStats(): array { // 按服务类型统计 $typeStats = ThirdPartyService::selectRaw('type, count(*) as count') ->groupBy('type') ->get() ->mapWithKeys(function ($item) { $serviceType = SERVICE_TYPE::tryFrom($item->type); $label = $serviceType ? $serviceType->getLabel() : $item->type; return [$label => $item->count]; }); // 按服务提供商统计 $providerStats = ThirdPartyService::selectRaw('provider, count(*) as count') ->groupBy('provider') ->orderByDesc('count') ->limit(10) ->get() ->pluck('count', 'provider'); // 按状态统计 $statusStats = ThirdPartyService::selectRaw('status, count(*) as count') ->groupBy('status') ->get() ->mapWithKeys(function ($item) { $status = SERVICE_STATUS::tryFrom($item->status); $label = $status ? $status->getLabel() : $item->status; return [$label => $item->count]; }); return [ 'by_type' => $typeStats, 'by_provider' => $providerStats, 'by_status' => $statusStats, ]; } /** * 获取健康状态统计 * * @return array */ protected function getHealthStats(): array { $healthStats = ThirdPartyService::selectRaw('health_status, count(*) as count') ->groupBy('health_status') ->get() ->pluck('count', 'health_status'); $recentChecks = ThirdPartyService::whereNotNull('last_health_check') ->where('last_health_check', '>=', now()->subHours(24)) ->count(); return [ 'status_distribution' => $healthStats, 'recent_checks' => $recentChecks, 'total_services' => ThirdPartyService::count(), ]; } /** * 获取使用统计数据 * * @return array */ protected function getUsageStats(): array { // 最近7天的API调用统计 $dailyStats = \App\Module\ThirdParty\Models\ThirdPartyLog::selectRaw('DATE(created_at) as date, count(*) as count') ->where('created_at', '>=', now()->subDays(7)) ->groupBy('date') ->orderBy('date') ->get() ->pluck('count', 'date'); // 按服务统计调用次数 $serviceStats = \App\Module\ThirdParty\Models\ThirdPartyLog::join('kku_thirdparty_services', 'kku_thirdparty_logs.service_id', '=', 'kku_thirdparty_services.id') ->selectRaw('kku_thirdparty_services.name, count(*) as count') ->groupBy('kku_thirdparty_services.id', 'kku_thirdparty_services.name') ->orderByDesc('count') ->limit(10) ->get() ->pluck('count', 'name'); return [ 'daily_calls' => $dailyStats, 'service_calls' => $serviceStats, ]; } /** * 构建快速操作卡片 * * @return string */ protected function buildQuickActionsCard() { return <<

快速操作

服务管理 凭证管理 调用日志 配额管理 监控记录
HTML; } /** * 构建最近日志卡片 * * @return string */ protected function buildRecentLogsCard() { $recentLogs = \App\Module\ThirdParty\Models\ThirdPartyLog::with('service') ->orderBy('created_at', 'desc') ->limit(5) ->get(); $logsHtml = ''; foreach ($recentLogs as $log) { $levelClass = $log->level === 'ERROR' ? 'danger' : ($log->level === 'WARNING' ? 'warning' : 'info'); $serviceName = $log->service ? $log->service->name : 'Unknown'; $timeAgo = $log->created_at->diffForHumans(); $logsHtml .= <<
{$log->level} {$serviceName}
{$timeAgo} HTML; } return <<

最近日志

{$logsHtml}
查看更多日志
HTML; } }