OpenApiRateLimit.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <?php
  2. namespace App\Module\OpenAPI\Models;
  3. use UCore\ModelCore;
  4. /**
  5. * OpenAPI频率限制记录模型
  6. *
  7. * @property int $id
  8. * @property string $app_id 应用ID
  9. * @property string $ip_address IP地址
  10. * @property string $endpoint 接口端点
  11. * @property string $limit_type 限制类型
  12. * @property \Carbon\Carbon $window_start 时间窗口开始
  13. * @property int $request_count 请求次数
  14. * @property bool $is_blocked 是否被阻止
  15. * @property string|null $user_agent 用户代理
  16. * @property array|null $headers 请求头信息
  17. * @property \Carbon\Carbon $created_at
  18. * @property \Carbon\Carbon $updated_at
  19. */
  20. class OpenApiRateLimit extends ModelCore
  21. {
  22. // field start
  23. * field end
  24. /**
  25. * 数据类型转换
  26. *
  27. * @var array
  28. */
  29. protected $casts = [
  30. 'window_start' => 'datetime',
  31. 'request_count' => 'integer',
  32. 'is_blocked' => 'boolean',
  33. 'headers' => 'array',
  34. ];
  35. /**
  36. * 关联应用模型
  37. *
  38. * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
  39. */
  40. public function app()
  41. {
  42. return $this->belongsTo(OpenApiApp::class, 'app_id', 'app_id');
  43. }
  44. /**
  45. * 获取限制类型的中文名称
  46. *
  47. * @return string
  48. */
  49. public function getLimitTypeNameAttribute(): string
  50. {
  51. return match ($this->limit_type) {
  52. 'requests_per_minute' => '每分钟请求数',
  53. 'requests_per_hour' => '每小时请求数',
  54. 'requests_per_day' => '每天请求数',
  55. 'requests_per_week' => '每周请求数',
  56. 'requests_per_month' => '每月请求数',
  57. default => $this->limit_type,
  58. };
  59. }
  60. /**
  61. * 获取状态标签
  62. *
  63. * @return string
  64. */
  65. public function getStatusLabelAttribute(): string
  66. {
  67. return $this->is_blocked ? '已阻止' : '正常';
  68. }
  69. /**
  70. * 获取状态颜色
  71. *
  72. * @return string
  73. */
  74. public function getStatusColorAttribute(): string
  75. {
  76. return $this->is_blocked ? 'danger' : 'success';
  77. }
  78. /**
  79. * 按应用ID查询
  80. *
  81. * @param \Illuminate\Database\Eloquent\Builder $query
  82. * @param string $appId
  83. * @return \Illuminate\Database\Eloquent\Builder
  84. */
  85. public function scopeByApp($query, string $appId)
  86. {
  87. return $query->where('app_id', $appId);
  88. }
  89. /**
  90. * 按IP地址查询
  91. *
  92. * @param \Illuminate\Database\Eloquent\Builder $query
  93. * @param string $ip
  94. * @return \Illuminate\Database\Eloquent\Builder
  95. */
  96. public function scopeByIp($query, string $ip)
  97. {
  98. return $query->where('ip_address', $ip);
  99. }
  100. /**
  101. * 按限制类型查询
  102. *
  103. * @param \Illuminate\Database\Eloquent\Builder $query
  104. * @param string $limitType
  105. * @return \Illuminate\Database\Eloquent\Builder
  106. */
  107. public function scopeByLimitType($query, string $limitType)
  108. {
  109. return $query->where('limit_type', $limitType);
  110. }
  111. /**
  112. * 查询被阻止的记录
  113. *
  114. * @param \Illuminate\Database\Eloquent\Builder $query
  115. * @return \Illuminate\Database\Eloquent\Builder
  116. */
  117. public function scopeBlocked($query)
  118. {
  119. return $query->where('is_blocked', true);
  120. }
  121. /**
  122. * 按时间范围查询
  123. *
  124. * @param \Illuminate\Database\Eloquent\Builder $query
  125. * @param \Carbon\Carbon $start
  126. * @param \Carbon\Carbon $end
  127. * @return \Illuminate\Database\Eloquent\Builder
  128. */
  129. public function scopeInTimeRange($query, $start, $end)
  130. {
  131. return $query->whereBetween('window_start', [$start, $end]);
  132. }
  133. /**
  134. * 获取最近的限制记录
  135. *
  136. * @param \Illuminate\Database\Eloquent\Builder $query
  137. * @param int $hours
  138. * @return \Illuminate\Database\Eloquent\Builder
  139. */
  140. public function scopeRecent($query, int $hours = 24)
  141. {
  142. return $query->where('window_start', '>=', now()->subHours($hours));
  143. }
  144. }