Browse Source

表头过滤器增加对whereHasIn以及json字段查询支持 #416

jqh 4 years ago
parent
commit
83823b41d2

+ 56 - 3
src/Grid/Column/Filter.php

@@ -5,7 +5,10 @@ namespace Dcat\Admin\Grid\Column;
 use Dcat\Admin\Grid\Column;
 use Dcat\Admin\Grid\Model;
 use Dcat\Admin\Support\Helper;
+use Dcat\Laravel\Database\WhereHasInServiceProvider;
 use Illuminate\Contracts\Support\Renderable;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Str;
 
 abstract class Filter implements Renderable
 {
@@ -22,7 +25,7 @@ abstract class Filter implements Renderable
     /**
      * @var string
      */
-    protected $getColumnName;
+    protected $columnName;
 
     /**
      * @var \Closure[]
@@ -81,7 +84,7 @@ abstract class Filter implements Renderable
      */
     public function setColumnName(string $name)
     {
-        $this->getColumnName = $name;
+        $this->columnName = $name;
 
         return $this;
     }
@@ -93,7 +96,15 @@ abstract class Filter implements Renderable
      */
     public function getColumnName()
     {
-        return $this->getColumnName ?: $this->parent->getName();
+        return str_replace(['.', '->'], '_', $this->getOriginalColumnName());
+    }
+
+    /**
+     * @return mixed
+     */
+    public function getOriginalColumnName()
+    {
+        return $this->columnName ?: $this->parent->getName();
     }
 
     /**
@@ -118,6 +129,48 @@ abstract class Filter implements Renderable
         return request($this->getQueryName(), $default);
     }
 
+    /**
+     * @param mixed $model
+     * @param string $query
+     * @param mixed array $params
+     *
+     * @return void
+     */
+    protected function withQuery($model, string $query, array $params)
+    {
+        $column = $this->getOriginalColumnName();
+
+        if (! Str::contains($column, '.')) {
+            $model->$query($column, ...$params);
+
+            return;
+        }
+
+        $this->withRelationQuery($model, $query, $params);
+    }
+
+    /**
+     * @param mixed $model
+     * @param string $query
+     * @param mixed ...$params
+     *
+     * @return void
+     */
+    protected function withRelationQuery($model, string $query, array $params)
+    {
+        $column = $this->getOriginalColumnName();
+
+        $relation = substr($column, 0, strrpos($column, '.'));
+        array_unshift($params, Arr::last(explode('.', $column)));
+
+        // 增加对whereHasIn的支持
+        $method = class_exists(WhereHasInServiceProvider::class) ? 'whereHasIn' : 'whereHas';
+
+        $model->$method($relation, function ($relation) use ($params, $query) {
+            $relation->$query(...$params);
+        });
+    }
+
     /**
      * Add reset button.
      */

+ 7 - 3
src/Grid/Column/Filter/Between.php

@@ -102,14 +102,18 @@ class Between extends Filter
         }
 
         if (! isset($value['start'])) {
-            return $model->where($this->getColumnName(), '<=', $value['end']);
+            $this->withQuery($model, 'where', ['<=', $value['end']]);
+
+            return;
         }
 
         if (! isset($value['end'])) {
-            return $model->where($this->getColumnName(), '=>', $value['start']);
+            $this->withQuery($model, 'where', ['>=', $value['start']]);
+
+            return;
         }
 
-        return $model->whereBetween($this->getColumnName(), array_values($value));
+        $this->withQuery($model, 'whereBetween', array_values($value));
     }
 
     protected function addScript()

+ 1 - 1
src/Grid/Column/Filter/Equal.php

@@ -98,7 +98,7 @@ class Equal extends Filter
             return;
         }
 
-        $model->where($this->getColumnName(), $value);
+        $this->withQuery($model, 'where', [$value]);
     }
 
     /**

+ 1 - 1
src/Grid/Column/Filter/Gt.php

@@ -19,6 +19,6 @@ class Gt extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), '>', $value);
+        $this->withQuery($model, 'where', ['>', $value]);
     }
 }

+ 1 - 1
src/Grid/Column/Filter/In.php

@@ -41,7 +41,7 @@ class In extends Filter
             return;
         }
 
-        $model->whereIn($this->getColumnName(), $value);
+        $this->withQuery($model, 'whereIn', [$value]);
     }
 
     /**

+ 1 - 1
src/Grid/Column/Filter/Like.php

@@ -19,6 +19,6 @@ class Like extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), 'like', "%{$value}%");
+        $this->withQuery($model, 'where', ['like', "%{$value}%"]);
     }
 }

+ 1 - 1
src/Grid/Column/Filter/Lt.php

@@ -19,6 +19,6 @@ class Lt extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), '<', $value);
+        $this->withQuery($model, 'where', ['<', $value]);
     }
 }

+ 1 - 1
src/Grid/Column/Filter/Ngt.php

@@ -19,6 +19,6 @@ class Ngt extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), '<=', $value);
+        $this->withQuery($model, 'where', ['<=', $value]);
     }
 }

+ 1 - 1
src/Grid/Column/Filter/Nlt.php

@@ -19,6 +19,6 @@ class Nlt extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), '>=', $value);
+        $this->withQuery($model, 'where', ['>=', $value]);
     }
 }

+ 1 - 1
src/Grid/Column/Filter/StartWith.php

@@ -19,6 +19,6 @@ class StartWith extends Equal
             return;
         }
 
-        $model->where($this->getColumnName(), 'like', "{$value}%");
+        $this->withQuery($model, 'where', ['like', "{$value}%"]);
     }
 }

+ 5 - 1
src/Grid/Filter/AbstractFilter.php

@@ -10,6 +10,7 @@ use Dcat\Admin\Grid\Filter\Presenter\Presenter;
 use Dcat\Admin\Grid\Filter\Presenter\Radio;
 use Dcat\Admin\Grid\Filter\Presenter\Select;
 use Dcat\Admin\Grid\Filter\Presenter\Text;
+use Dcat\Laravel\Database\WhereHasInServiceProvider;
 use Illuminate\Support\Arr;
 use Illuminate\Support\Collection;
 
@@ -521,7 +522,10 @@ abstract class AbstractFilter
         $relation = substr($this->column, 0, strrpos($this->column, '.'));
         $params[0] = Arr::last(explode('.', $this->column));
 
-        return ['whereHas' => [$relation, function ($relation) use ($params) {
+        // 增加对whereHasIn的支持
+        $method = class_exists(WhereHasInServiceProvider::class) ? 'whereHasIn' : 'whereHas';
+
+        return [$method => [$relation, function ($relation) use ($params) {
             call_user_func_array([$relation, $this->query], $params);
         }]];
     }