| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- <?php
- namespace App\Module\ThirdParty\Services;
- use App\Module\ThirdParty\Dto\Config;
- use App\Module\ThirdParty\Dto\Credential;
- use App\Module\ThirdParty\Models\ThirdPartyService as ServiceModel;
- use App\Module\ThirdParty\Models\ThirdPartyCredential;
- use App\Module\ThirdParty\Models\ThirdPartyLog;
- use App\Module\ThirdParty\Models\ThirdPartyQuota;
- use App\Module\ThirdParty\Enums\SERVICE_STATUS;
- use App\Module\ThirdParty\Enums\LOG_LEVEL;
- use Illuminate\Support\Facades\Http;
- use Illuminate\Support\Facades\Cache;
- use Illuminate\Http\Client\Response;
- /**
- * 第三方请求基类
- *
- * 抽象化请求概念,不局限于HTTP请求,扩展到调用包的请求方法
- * 基类处理配置读取、配额管理、日志记录等通用功能
- */
- abstract class BaseRequest
- {
- /**
- * 服务代码
- */
- protected string $serviceCode;
- /**
- * 服务配置
- */
- protected ?ServiceModel $service = null;
- /**
- * 认证凭证
- */
- protected ?ThirdPartyCredential $credential = null;
- /**
- * 请求ID
- */
- protected string $requestId;
- /**
- * 开始时间
- */
- protected float $startTime;
- /**
- * 构造函数
- *
- * @param string $serviceCode 服务代码
- */
- public function __construct(string $serviceCode)
- {
- $this->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->service->getActiveCredential();
- 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;
- abstract protected function getCredential(string $params = ''): Credential;
- abstract protected function getConfig(string $params = ''): Config;
- /**
- * 检查配额
- *
- * @return bool
- */
- protected function checkQuota(): bool
- {
- return QuotaService::checkQuota($this->service);
- }
- /**
- * 更新配额
- */
- protected function updateQuota(): void
- {
- QuotaService::updateQuota($this->service);
- }
- /**
- * 记录请求日志
- *
- * @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;
- }
- }
|