123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- <?php
- namespace App\Filters;
- use Illuminate\Database\Eloquent\Builder;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Log;
- use Illuminate\Support\Str;
- abstract class Filter
- {
- protected $request;
- /**
- * @var Builder
- */
- protected $builder;
- protected $filters = [];
- protected $simpleFilters = [];
- public function __construct(Request $request)
- {
- $this->request = $request;
- $this->formatSimpleFilters();
- }
- /**
- * 把 simpleFilters 中没有指定过滤类型的, 自动改为 '='
- */
- protected function formatSimpleFilters()
- {
- $t = [];
- foreach ($this->simpleFilters as $field => $op) {
- if (is_int($field)) {
- $t[$op] = 'equal';
- } else {
- $t[$field] = $op;
- }
- }
- $this->simpleFilters = $t;
- }
- /**
- * 应用过滤
- *
- * @param $builder
- *
- * @return mixed
- */
- public function apply($builder)
- {
- $this->builder = $builder;
- foreach ($this->getFilters() as $filter => $value) {
- if (is_null($value)) {
- continue;
- }
- if ($op = $this->simpleFilters[$filter] ?? null) { // 简单过滤应用
- $this->applySimpleFilter($filter, $op, $value);
- } else { // 其他自定义过滤
- $method = Str::camel($filter);
- if (method_exists($this, $method)) {
- $this->$method($value);
- }
- }
- }
- return $this->builder;
- }
- /**
- * 过滤简单过滤器
- *
- * @param string $filter 过滤字段
- * @param string|array $op 操作
- * @param mixed $value 请求中对应的值
- */
- protected function applySimpleFilter($filter, $op, $value)
- {
- if (is_array($op)) {
- $args = array_slice($op, 1);
- $op = $op[0];
- }
- switch ($op) {
- case 'equal':
- $this->builder->where($filter, $value);
- break;
- case 'like':
- $this->builder->where($filter, 'like', str_replace('?', $value, $args[0]));
- break;
- case 'in':
- if (is_string($value)) {
- $value = explode(',', $value);
- }
- $this->builder->whereIn($filter, $value);
- break;
- case 'lt': // 小于
- $this->builder->where($filter,'<',$value);
- break;
- case 'time_lt': // 小于时间
- $this->builder->where($filter,'<',date('Y-m-d H:i:s',strtotime($value)));
- break;
- case 'put_area': // 投放区域
- $this->builder->where('area_id',$value);
- break;
- case 'pay_time_between': // 支付时间区间筛选
- $this->builder->where('pay_time','>',date('Y-m-d H:i:s',strtotime($value[0])))
- ->where('pay_time','<',date('Y-m-d H:i:s',strtotime($value[1])));
- break;
- default:
- // do nothing
- }
- }
- public function getFilters()
- {
- return $this->request->only(array_merge($this->filters, array_keys($this->simpleFilters)));
- }
- /**
- * 只保留特定的过滤字段
- *
- * @param array|string $only
- *
- * @return $this
- */
- public function only($only)
- {
- if (is_string($only)) {
- $only = [$only];
- }
- $this->filters = array_intersect($this->filters, $only);
- $this->simpleFilters = array_intersect($this->simpleFilters, $only);
- return $this;
- }
- }
|