OpenApiRateLimit.php 4.4 KB

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