123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- <?php
- namespace App\Filters;
- use Carbon\Carbon;
- 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': // 小于时间 // 值必须为时间戳
- if ((int)$value < 10) {
- $time = Carbon::now()->subDays((int)$value)->format('Y-m-d H:i:s');
- $this->builder->where($filter, '<', $time);
- } else {
- $this->builder->where($filter, '<', date('Y-m-d H:i:s', $value));
- }
- break;
- case 'put_area': // 投放区域
- $this->builder->where('area_id', $value);
- break;
- case 'pay_time_between': // 支付时间区间筛选
- $this->builder->where('pay_time', '>', Carbon::parse($value[0])->format('Y-m-d H:i:s'))
- ->where('pay_time', '<', Carbon::parse($value[1])->format('Y-m-d H:i:s'));
- break;
- case 'created_time_between': // created_at时间区间筛选
- // Log::info($value);
- $this->builder->where(function ($q) use ($value) {
- $q->where('created_at', '>', Carbon::parse($value[0])->format('Y-m-d H:i:s'))
- ->where('created_at', '<', Carbon::parse($value[1])->format('Y-m-d H:i:s'));
- });
- 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;
- }
- }
|