Filter.php 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. namespace App\Filters;
  3. use Illuminate\Database\Eloquent\Builder;
  4. use Illuminate\Http\Request;
  5. use Illuminate\Support\Facades\Log;
  6. use Illuminate\Support\Str;
  7. abstract class Filter
  8. {
  9. protected $request;
  10. /**
  11. * @var Builder
  12. */
  13. protected $builder;
  14. protected $filters = [];
  15. protected $simpleFilters = [];
  16. public function __construct(Request $request)
  17. {
  18. $this->request = $request;
  19. $this->formatSimpleFilters();
  20. }
  21. /**
  22. * 把 simpleFilters 中没有指定过滤类型的, 自动改为 '='
  23. */
  24. protected function formatSimpleFilters()
  25. {
  26. $t = [];
  27. foreach ($this->simpleFilters as $field => $op) {
  28. if (is_int($field)) {
  29. $t[$op] = 'equal';
  30. } else {
  31. $t[$field] = $op;
  32. }
  33. }
  34. $this->simpleFilters = $t;
  35. }
  36. /**
  37. * 应用过滤
  38. *
  39. * @param $builder
  40. *
  41. * @return mixed
  42. */
  43. public function apply($builder)
  44. {
  45. $this->builder = $builder;
  46. foreach ($this->getFilters() as $filter => $value) {
  47. if (is_null($value)) {
  48. continue;
  49. }
  50. if ($op = $this->simpleFilters[$filter] ?? null) { // 简单过滤应用
  51. $this->applySimpleFilter($filter, $op, $value);
  52. } else { // 其他自定义过滤
  53. $method = Str::camel($filter);
  54. if (method_exists($this, $method)) {
  55. $this->$method($value);
  56. }
  57. }
  58. }
  59. return $this->builder;
  60. }
  61. /**
  62. * 过滤简单过滤器
  63. *
  64. * @param string $filter 过滤字段
  65. * @param string|array $op 操作
  66. * @param mixed $value 请求中对应的值
  67. */
  68. protected function applySimpleFilter($filter, $op, $value)
  69. {
  70. if (is_array($op)) {
  71. $args = array_slice($op, 1);
  72. $op = $op[0];
  73. }
  74. switch ($op) {
  75. case 'equal':
  76. $this->builder->where($filter, $value);
  77. break;
  78. case 'like':
  79. $this->builder->where($filter, 'like', str_replace('?', $value, $args[0]));
  80. break;
  81. case 'in':
  82. if (is_string($value)) {
  83. $value = explode(',', $value);
  84. }
  85. $this->builder->whereIn($filter, $value);
  86. break;
  87. case 'lt': // 小于
  88. $this->builder->where($filter,'<',$value);
  89. break;
  90. case 'time_lt': // 小于时间
  91. $this->builder->where($filter,'<',date('Y-m-d H:i:s',strtotime($value)));
  92. break;
  93. case 'put_area': // 投放区域
  94. $this->builder->where('area_id',$value);
  95. break;
  96. case 'pay_time_between': // 支付时间区间筛选
  97. $this->builder->where('pay_time','>',date('Y-m-d H:i:s',strtotime($value[0])))
  98. ->where('pay_time','<',date('Y-m-d H:i:s',strtotime($value[1])));
  99. break;
  100. default:
  101. // do nothing
  102. }
  103. }
  104. public function getFilters()
  105. {
  106. return $this->request->only(array_merge($this->filters, array_keys($this->simpleFilters)));
  107. }
  108. /**
  109. * 只保留特定的过滤字段
  110. *
  111. * @param array|string $only
  112. *
  113. * @return $this
  114. */
  115. public function only($only)
  116. {
  117. if (is_string($only)) {
  118. $only = [$only];
  119. }
  120. $this->filters = array_intersect($this->filters, $only);
  121. $this->simpleFilters = array_intersect($this->simpleFilters, $only);
  122. return $this;
  123. }
  124. }