ThirdPartyService.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <?php
  2. namespace App\Module\ThirdParty\Models;
  3. use UCore\ModelCore;
  4. use App\Module\ThirdParty\Enums\SERVICE_TYPE;
  5. use App\Module\ThirdParty\Enums\AUTH_TYPE;
  6. use App\Module\ThirdParty\Enums\SERVICE_STATUS;
  7. use Illuminate\Database\Eloquent\Relations\HasMany;
  8. /**
  9. * 第三方服务模型
  10. *
  11. * field start
  12. * @property int $id 主键ID
  13. * @property string $name 服务名称
  14. * @property string $code 服务代码(唯一标识)
  15. * @property string $type 服务类型
  16. * @property string $provider 服务提供商
  17. * @property string $description 服务描述
  18. * @property string $base_url 基础URL
  19. * @property string $version API版本
  20. * @property string $auth_type 认证类型
  21. * @property string $status 服务状态
  22. * @property int $priority 优先级(数字越小优先级越高)
  23. * @property int $timeout 超时时间(秒)
  24. * @property int $retry_times 重试次数
  25. * @property int $retry_delay 重试延迟(毫秒)
  26. * @property array $config 服务配置信息
  27. * @property array $headers 默认请求头
  28. * @property array $params 默认参数
  29. * @property string $webhook_url Webhook回调地址
  30. * @property string $webhook_secret Webhook密钥
  31. * @property string $health_check_url 健康检查URL
  32. * @property int $health_check_interval 健康检查间隔(秒)
  33. * @property \Carbon\Carbon $last_health_check 最后健康检查时间
  34. * @property string $health_status 健康状态
  35. * @property \Carbon\Carbon $created_at 创建时间
  36. * @property \Carbon\Carbon $updated_at 更新时间
  37. * field end
  38. */
  39. class ThirdPartyService extends ModelCore
  40. {
  41. /**
  42. * 数据表名
  43. *
  44. * @var string
  45. */
  46. protected $table = 'thirdparty_services';
  47. /**
  48. * 属性类型转换
  49. *
  50. * @var array
  51. */
  52. protected $casts = [
  53. 'config' => 'array',
  54. 'headers' => 'array',
  55. 'params' => 'array',
  56. 'priority' => 'integer',
  57. 'timeout' => 'integer',
  58. 'retry_times' => 'integer',
  59. 'retry_delay' => 'integer',
  60. 'health_check_interval' => 'integer',
  61. 'last_health_check' => 'datetime',
  62. 'created_at' => 'datetime',
  63. 'updated_at' => 'datetime',
  64. ];
  65. /**
  66. * 获取服务类型枚举
  67. *
  68. * @return SERVICE_TYPE
  69. */
  70. public function getServiceTypeEnum(): SERVICE_TYPE
  71. {
  72. return SERVICE_TYPE::from($this->type);
  73. }
  74. /**
  75. * 获取认证类型枚举
  76. *
  77. * @return AUTH_TYPE
  78. */
  79. public function getAuthTypeEnum(): AUTH_TYPE
  80. {
  81. return AUTH_TYPE::from($this->auth_type);
  82. }
  83. /**
  84. * 获取服务状态枚举
  85. *
  86. * @return SERVICE_STATUS
  87. */
  88. public function getServiceStatusEnum(): SERVICE_STATUS
  89. {
  90. return SERVICE_STATUS::from($this->status);
  91. }
  92. /**
  93. * 获取服务类型标签
  94. *
  95. * @return string
  96. */
  97. public function getTypeLabel(): string
  98. {
  99. return $this->getServiceTypeEnum()->getLabel();
  100. }
  101. /**
  102. * 获取认证类型标签
  103. *
  104. * @return string
  105. */
  106. public function getAuthTypeLabel(): string
  107. {
  108. return $this->getAuthTypeEnum()->getLabel();
  109. }
  110. /**
  111. * 获取状态标签
  112. *
  113. * @return string
  114. */
  115. public function getStatusLabel(): string
  116. {
  117. return $this->getServiceStatusEnum()->getLabel();
  118. }
  119. /**
  120. * 检查服务是否可用
  121. *
  122. * @return bool
  123. */
  124. public function isAvailable(): bool
  125. {
  126. return $this->getServiceStatusEnum()->isAvailable();
  127. }
  128. /**
  129. * 检查服务是否可以调用API
  130. *
  131. * @return bool
  132. */
  133. public function canCallApi(): bool
  134. {
  135. return $this->getServiceStatusEnum()->canCallApi();
  136. }
  137. /**
  138. * 检查服务是否需要关注
  139. *
  140. * @return bool
  141. */
  142. public function needsAttention(): bool
  143. {
  144. return $this->getServiceStatusEnum()->needsAttention();
  145. }
  146. /**
  147. * 获取完整的API URL
  148. *
  149. * @param string $endpoint
  150. * @return string
  151. */
  152. public function getApiUrl(string $endpoint = ''): string
  153. {
  154. $baseUrl = rtrim($this->base_url, '/');
  155. $endpoint = ltrim($endpoint, '/');
  156. if (empty($endpoint)) {
  157. return $baseUrl;
  158. }
  159. return $baseUrl . '/' . $endpoint;
  160. }
  161. /**
  162. * 获取默认请求头
  163. *
  164. * @return array
  165. */
  166. public function getDefaultHeaders(): array
  167. {
  168. $headers = $this->headers ?? [];
  169. // 添加认证相关的默认头
  170. $authType = $this->getAuthTypeEnum();
  171. if ($authType->getHeaderName()) {
  172. $headers['Content-Type'] = 'application/json';
  173. $headers['Accept'] = 'application/json';
  174. }
  175. return $headers;
  176. }
  177. /**
  178. * 获取默认参数
  179. *
  180. * @return array
  181. */
  182. public function getDefaultParams(): array
  183. {
  184. return $this->params ?? [];
  185. }
  186. /**
  187. * 关联认证凭证
  188. *
  189. * @return HasMany
  190. */
  191. public function credentials(): HasMany
  192. {
  193. return $this->hasMany(ThirdPartyCredential::class, 'service_id');
  194. }
  195. /**
  196. * 关联调用日志
  197. *
  198. * @return HasMany
  199. */
  200. public function logs(): HasMany
  201. {
  202. return $this->hasMany(ThirdPartyLog::class, 'service_id');
  203. }
  204. /**
  205. * 关联配额管理
  206. *
  207. * @return HasMany
  208. */
  209. public function quotas(): HasMany
  210. {
  211. return $this->hasMany(ThirdPartyQuota::class, 'service_id');
  212. }
  213. /**
  214. * 关联监控记录
  215. *
  216. * @return HasMany
  217. */
  218. public function monitors(): HasMany
  219. {
  220. return $this->hasMany(ThirdPartyMonitor::class, 'service_id');
  221. }
  222. /**
  223. * 获取激活的凭证
  224. *
  225. * @param string $environment
  226. * @return ThirdPartyCredential|null
  227. */
  228. public function getActiveCredential(string $environment = 'production'): ?ThirdPartyCredential
  229. {
  230. return $this->credentials()
  231. ->where('is_active', true)
  232. ->where('environment', $environment)
  233. ->where(function ($query) {
  234. $query->whereNull('expires_at')
  235. ->orWhere('expires_at', '>', now());
  236. })
  237. ->first();
  238. }
  239. /**
  240. * 更新健康状态
  241. *
  242. * @param string $status
  243. * @return bool
  244. */
  245. public function updateHealthStatus(string $status): bool
  246. {
  247. return $this->update([
  248. 'health_status' => $status,
  249. 'last_health_check' => now(),
  250. ]);
  251. }
  252. /**
  253. * 检查是否需要健康检查
  254. *
  255. * @return bool
  256. */
  257. public function needsHealthCheck(): bool
  258. {
  259. if (!$this->health_check_url) {
  260. return false;
  261. }
  262. if (!$this->last_health_check) {
  263. return true;
  264. }
  265. $nextCheck = $this->last_health_check->addSeconds($this->health_check_interval);
  266. return now()->gte($nextCheck);
  267. }
  268. /**
  269. * 生成唯一的服务代码
  270. *
  271. * @param string $name
  272. * @param string $provider
  273. * @return string
  274. */
  275. public static function generateCode(string $name, string $provider): string
  276. {
  277. $code = strtolower($provider . '_' . str_replace(' ', '_', $name));
  278. $code = preg_replace('/[^a-z0-9_]/', '', $code);
  279. // 确保代码唯一
  280. $counter = 1;
  281. $originalCode = $code;
  282. while (static::where('code', $code)->exists()) {
  283. $code = $originalCode . '_' . $counter;
  284. $counter++;
  285. }
  286. return $code;
  287. }
  288. }