dispatchService = $dispatchService; } /** * 处理Webhook请求 * * @param Request $request 请求对象 * @param string $packageName 包名 * @param string $handlerRoute Handler路由 * @return JsonResponse */ public function dispatch(Request $request, string $packageName, string $handlerRoute): JsonResponse { $requestId = uniqid('webhook_dispatch_', true); $startTime = microtime(true); // 初始化请求日志记录器 $requestLogger = new \App\Module\System\Services\RequestLogger($request); $requestLogger->setRouter("webhook/{$packageName}/{$handlerRoute}"); try { Log::info("Webhook分发开始", [ 'request_id' => $requestId, 'package_name' => $packageName, 'handler_route' => $handlerRoute, 'method' => $request->method(), 'url' => $request->fullUrl(), 'ip' => $request->ip(), ]); // 验证包名格式 $this->validatePackageName($packageName); // 验证Handler路由格式 $this->validateHandlerRoute($handlerRoute); // 分发到具体的处理器 $result = $this->dispatchService->dispatch($packageName, $handlerRoute, $request); Log::info("Webhook分发成功", [ 'request_id' => $requestId, 'package_name' => $packageName, 'handler_route' => $handlerRoute, 'result' => $result, ]); // 记录运行时间 $requestLogger->setRunTime($startTime); // 构建响应数据 $responseData = [ 'success' => $result['success'], 'data' => $result['data']??[], 'request_id' => $requestId, ]; // 记录JSON响应 $requestLogger->setJsonResponse(json_encode($responseData)); return response()->json($responseData); } catch (\Exception $e) { Log::error("Webhook分发失败", [ 'request_id' => $requestId, 'package_name' => $packageName, 'handler_route' => $handlerRoute, 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); // 记录错误信息和运行时间 $requestLogger->setError($e->getMessage()); $requestLogger->setRunTime($startTime); // 构建错误响应数据 $errorResponseData = [ 'success' => false, 'error' => $e->getMessage(), 'request_id' => $requestId, ]; // 记录JSON响应 $requestLogger->setJsonResponse(json_encode($errorResponseData)); return response()->json($errorResponseData, 400); } } /** * 验证包名格式 * * @param string $packageName 包名 * @throws \Exception */ protected function validatePackageName(string $packageName): void { // 包名只能包含字母、数字、下划线 if (!preg_match('/^[a-zA-Z][a-zA-Z0-9_]*$/', $packageName)) { throw new \Exception("无效的包名格式: {$packageName}"); } // 包名长度限制 if (strlen($packageName) > 50) { throw new \Exception("包名长度不能超过50个字符: {$packageName}"); } } /** * 验证Handler路由格式 * * @param string $handlerRoute Handler路由 * @throws \Exception */ protected function validateHandlerRoute(string $handlerRoute): void { // Handler路由只能包含字母、数字、下划线、斜杠 if (!preg_match('/^[a-zA-Z0-9_\/]+$/', $handlerRoute)) { throw new \Exception("无效的Handler路由格式: {$handlerRoute}"); } // Handler路由长度限制 if (strlen($handlerRoute) > 100) { throw new \Exception("Handler路由长度不能超过100个字符: {$handlerRoute}"); } // 不能以斜杠开头或结尾 if (str_starts_with($handlerRoute, '/') || str_ends_with($handlerRoute, '/')) { throw new \Exception("Handler路由不能以斜杠开头或结尾: {$handlerRoute}"); } } /** * 健康检查接口 * * @return JsonResponse */ public function health(): JsonResponse { return response()->json([ 'success' => true, 'message' => 'ThirdParty Webhook分发服务运行正常', 'timestamp' => now()->toISOString(), ]); } /** * 获取已注册的包列表 * * @return JsonResponse */ public function packages(): JsonResponse { try { $packages = $this->dispatchService->getRegisteredPackages(); return response()->json([ 'success' => true, 'data' => $packages, ]); } catch (\Exception $e) { return response()->json([ 'success' => false, 'error' => $e->getMessage(), ], 500); } } }