serviceCode = $serviceCode; $this->requestId = uniqid('req_', true); $this->startTime = microtime(true); // 初始化服务配置 $this->initializeService(); } /** * 初始化服务配置 * * @throws \Exception */ protected function initializeService(): void { $this->service = ServiceModel::where('code', $this->serviceCode)->first(); if (!$this->service) { throw new \Exception("服务 {$this->serviceCode} 不存在"); } if (!$this->service->canCallApi()) { throw new \Exception("服务 {$this->serviceCode} 当前不可用,状态:{$this->service->getStatusLabel()}"); } // 获取认证凭证 - 智能环境匹配 $this->credential = $this->getSmartCredential(); if (!$this->credential) { throw new \Exception("服务 {$this->serviceCode} 没有可用的认证凭证"); } } /** * 执行请求 * * @param array $params 请求参数 * @return array * @throws \Exception */ public function request(array $params = []): array { // 检查配额 if (!$this->checkQuota()) { throw new \Exception("服务 {$this->serviceCode} 配额已用完"); } try { // 执行具体的请求逻辑 $result = $this->handler($params); // 记录成功日志 $this->logRequest($params, $result, true); // 更新配额 $this->updateQuota(); // 更新凭证使用统计 $this->credential->updateUsageStats(); return $result; } catch (\Exception $e) { // 记录失败日志 $this->logRequest($params, [ 'error' => $e->getMessage() ], false); throw $e; } } /** * 具体的请求处理逻辑(由子类实现) * * @param array $params 请求参数 * @return array */ abstract protected function handler(array $params = []): array; /** * 检查配额 * * @return bool */ protected function checkQuota(): bool { return QuotaService::canUse($this->service->id); } /** * 更新配额 */ protected function updateQuota(): void { QuotaService::use($this->service->id); } /** * 记录请求日志 * * @param array $params 请求参数 * @param array $result 响应结果 * @param bool $success 是否成功 */ protected function logRequest(array $params, array $result, bool $success): void { $responseTime = (int)((microtime(true) - $this->startTime) * 1000); ThirdPartyLog::create([ 'service_id' => $this->service->id, 'credential_id' => $this->credential->id, 'request_id' => $this->requestId, 'method' => 'PACKAGE_CALL', 'url' => $this->serviceCode, 'request_headers' => json_encode([]), 'request_body' => json_encode($params), 'response_status' => $success ? 200 : 500, 'response_headers' => json_encode([]), 'response_body' => json_encode($result), 'response_time' => $responseTime, 'success' => $success, 'error_message' => $success ? null : ($result['error'] ?? '未知错误'), 'level' => $success ? LOG_LEVEL::INFO->value : LOG_LEVEL::ERROR->value, 'ip_address' => request()->ip(), 'user_agent' => request()->userAgent(), 'called_at' => now(), ]); } /** * 获取服务配置 * * @param string|null $key 配置键名,为空则返回全部配置 * @return mixed */ protected function getConfig(?string $key = null) { $config = $this->service->config ?? []; if ($key === null) { return $config; } return $config[$key] ?? null; } /** * 获取服务信息 * * @return ServiceModel */ protected function getService(): ServiceModel { return $this->service; } /** * 获取认证凭证 * * @return ThirdPartyCredential */ protected function getCredential(): ThirdPartyCredential { return $this->credential; } /** * 获取请求ID * * @return string */ protected function getRequestId(): string { return $this->requestId; } /** * 智能获取认证凭证 * * 按优先级查找可用的认证凭证: * 1. 当前应用环境对应的凭证 * 2. testing环境凭证 * 3. production环境凭证 * 4. 任何可用的激活凭证 * * @return ThirdPartyCredential|null */ protected function getSmartCredential(): ?ThirdPartyCredential { $appEnv = app()->environment(); // 环境映射:将Laravel环境映射到凭证环境 $envMapping = [ 'local' => 'testing', 'development' => 'testing', 'testing' => 'testing', 'staging' => 'staging', 'production' => 'production', ]; $preferredEnv = $envMapping[$appEnv] ?? 'production'; // 按优先级尝试获取凭证 $environments = [$preferredEnv, 'testing', 'production']; $environments = array_unique($environments); // 去重 foreach ($environments as $env) { $credential = $this->service->getActiveCredential($env); if ($credential) { return $credential; } } // 如果以上都没找到,尝试获取任何可用的激活凭证 return $this->service->credentials() ->where('is_active', true) ->where(function ($query) { $query->whereNull('expires_at') ->orWhere('expires_at', '>', now()); }) ->first(); } }