mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-12-01 22:50:44 +00:00
122 lines
3.6 KiB
PHP
122 lines
3.6 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Filters;
|
||
|
|
|
||
|
|
use Illuminate\Http\Request;
|
||
|
|
use Illuminate\Support\Str;
|
||
|
|
use Illuminate\Support\Arr;
|
||
|
|
|
||
|
|
class Filters
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* @var Request
|
||
|
|
*/
|
||
|
|
protected $request;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* The Eloquent builder.
|
||
|
|
*
|
||
|
|
* @var \Illuminate\Database\Eloquent\Builder
|
||
|
|
*/
|
||
|
|
protected $builder;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Registered filters to operate upon.
|
||
|
|
*
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $filters = [];
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new ThreadFilters instance.
|
||
|
|
*
|
||
|
|
* @param Request $request
|
||
|
|
*/
|
||
|
|
public function __construct()
|
||
|
|
{
|
||
|
|
$this->request = Request();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Apply the filters.
|
||
|
|
*
|
||
|
|
* @param \Illuminate\Database\Eloquent\Builder $builder
|
||
|
|
* @return \Illuminate\Database\Eloquent\Builder
|
||
|
|
*/
|
||
|
|
public function apply($builder)
|
||
|
|
{
|
||
|
|
$this->builder = $builder;
|
||
|
|
$fieldsSearchable = $this->getFieldsSearchable();
|
||
|
|
$fields = $this->getFilters($fieldsSearchable);
|
||
|
|
if (is_array($fields) && count($fields) && is_array($fieldsSearchable) && count($fieldsSearchable)) {
|
||
|
|
foreach ($fields as $field => $value) {
|
||
|
|
$method = Str::camel($field);
|
||
|
|
if (method_exists($this, $method)) {
|
||
|
|
$this->$method($value);
|
||
|
|
} elseif (isset($fieldsSearchable[$field])) {
|
||
|
|
$condition = $fieldsSearchable[$field];
|
||
|
|
$value = $condition == "like" ? "%{$value}%" : $value;
|
||
|
|
$relation = null;
|
||
|
|
if (stripos($field, '.')) {
|
||
|
|
$explode = explode('.', $field);
|
||
|
|
$field = array_pop($explode);
|
||
|
|
$relation = implode('.', $explode);
|
||
|
|
}
|
||
|
|
$modelTableName = $builder->getModel()->getTable();
|
||
|
|
$field = Str::snake($field);
|
||
|
|
if (!is_null($value)) {
|
||
|
|
if (!is_null($relation)) {
|
||
|
|
$builder->whereHas($relation, function ($query) use ($field, $condition, $value) {
|
||
|
|
$query->where($field, $condition, $value);
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
$builder->where($modelTableName . '.' . $field, $condition, $value);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return $this->builder;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fetch all relevant filters from the request.
|
||
|
|
*
|
||
|
|
* @return array
|
||
|
|
*/
|
||
|
|
public function getFilters($fieldsSearchable)
|
||
|
|
{
|
||
|
|
if (!is_array($fieldsSearchable) || count($fieldsSearchable) == 0) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
$keys = array_keys($fieldsSearchable);
|
||
|
|
//$this->request->only() 会把user.nickname参数里包含"." 转换成数组
|
||
|
|
//Arr::dot 方法使用「.」号将将多维数组转化为一维数组:
|
||
|
|
|
||
|
|
return array_filter(Arr::dot($this->request->only($keys)), function ($value) {
|
||
|
|
return !is_null($value) && $value != '';
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
//获取model 可以查询的参数
|
||
|
|
protected function getFieldsSearchable()
|
||
|
|
{
|
||
|
|
$model = $this->builder->getModel();
|
||
|
|
if (!property_exists($model, 'fieldSearchable')) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
$fieldSearchable = $model->fieldSearchable;
|
||
|
|
$fields = [];
|
||
|
|
foreach ($fieldSearchable as $field => $condition) {
|
||
|
|
if (is_numeric($field)) {
|
||
|
|
$field = $condition;
|
||
|
|
$condition = "=";
|
||
|
|
}
|
||
|
|
$fields[$field] = $condition;
|
||
|
|
}
|
||
|
|
|
||
|
|
return $fields;
|
||
|
|
}
|
||
|
|
}
|