|
<?php |
|
/** |
|
* Created by PhpStorm. |
|
* User: aozhuochao |
|
* Date: 2018-12-13 |
|
* Time: 11:04 |
|
*/ |
|
|
|
namespace App\Helper\Traits; |
|
|
|
use Illuminate\Database\Eloquent\Builder; |
|
use Illuminate\Database\Query\Builder as QueryBuilder; |
|
use Illuminate\Pagination\Paginator; |
|
use Illuminate\Pagination\LengthAwarePaginator; |
|
|
|
/** |
|
* 通过scope给where扩展 |
|
* |
|
* @method Builder|QueryBuilder|$this ifWhere($bool, $column, $operator = null, $value = null, $boolean = 'and') |
|
* @method Builder|QueryBuilder|$this ifWhereIn($bool, $column, $values, $boolean = 'and', $not = false) |
|
* @method Builder|QueryBuilder|$this ifWhereBetween($bool, $column, array $values, $boolean = 'and', $not = false) |
|
* @method Builder|QueryBuilder|$this ifWith($bool, $relations) |
|
* @method static $this|Builder|QueryBuilder whereRange($field, $min = '', $max = '', $eq = '=') |
|
* @method static $this|Builder|QueryBuilder havingRange($field, $min = '', $max = '', $eq = '=') |
|
* @method \Illuminate\Contracts\Pagination\LengthAwarePaginator paginateRaw($query, $perPage = 15, $countRaw = 'count(*) as aggregate', $columns = ['*'], $pageName = 'page', $page = null) |
|
*/ |
|
trait ModelScopeWhereTrait |
|
{ |
|
/** |
|
* ifWhere,如果$bool为真就执行where条件 |
|
* |
|
* @param Builder $query |
|
* @param bool $bool 是否where |
|
* @param array $whereArgs |
|
* @return Builder|QueryBuilder|$this |
|
*/ |
|
public function scopeIfWhere($query, $bool, ...$whereArgs) |
|
{ |
|
if ($bool && !empty($whereArgs)){ |
|
$query->where(...$whereArgs); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* ifWhere,如果$bool为真就执行whereIn条件 |
|
* |
|
* @param Builder $query |
|
* @param bool $bool 是否where |
|
* @param array $whereArgs |
|
* @return Builder|QueryBuilder|$this |
|
*/ |
|
public function scopeIfWhereIn($query, $bool, ...$whereArgs) |
|
{ |
|
if ($bool && !empty($whereArgs)){ |
|
$query->whereIn(...$whereArgs); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* ifWhereBetween,如果$bool为真就执行whereBetween条件 |
|
* |
|
* @param Builder $query |
|
* @param bool $bool 是否whereBetween |
|
* @param array $whereArgs |
|
* @return Builder|QueryBuilder|$this |
|
*/ |
|
public function scopeIfWhereBetween($query, $bool, ...$whereArgs) |
|
{ |
|
if ($bool && !empty($whereArgs)){ |
|
$query->whereBetween(...$whereArgs); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* ifWith,如果$bool为真就执行with |
|
* |
|
* @param Builder $query |
|
* @param bool $bool 是否使用 |
|
* @param array ...$withArgs |
|
* @return Builder|QueryBuilder|$this |
|
*/ |
|
public function scopeIfWith($query, $bool, ...$withArgs) |
|
{ |
|
if ($bool && !empty($withArgs)){ |
|
$query->with(...$withArgs); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* where区间搜索,可单条件过滤 |
|
* |
|
* @param Builder|QueryBuilder $query |
|
* @param $field |
|
* @param $min |
|
* @param $max |
|
* @param string $eq |
|
* @return Builder|QueryBuilder |
|
*/ |
|
public function scopeWhereRange($query, $field, $min = '', $max = '', $eq = '=') |
|
{ |
|
if (!empty($min) && !empty($max) && $min > $max){ // 所有 |
|
return $query; |
|
} |
|
|
|
if (!empty($min) && !empty($max)){ // 指定两个 |
|
$query->whereBetween($field, [$min, $max]); |
|
|
|
return $query; |
|
} |
|
|
|
if (!empty($min)) { |
|
$query->where($field, '>' . $eq, $min); |
|
} |
|
if (!empty($max)) { |
|
$query->where($field, '<' . $eq, $max); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* where区间搜索,可单条件过滤 |
|
* |
|
* @param Builder|QueryBuilder $query |
|
* @param $field |
|
* @param $min |
|
* @param $max |
|
* @param string $eq |
|
* @return Builder|QueryBuilder |
|
*/ |
|
public function scopeHavingRange($query, $field, $min = '', $max = '', $eq = '=') |
|
{ |
|
if ($min > $max){ // 所有 |
|
return $query; |
|
} |
|
if (!empty($min) && !empty($max)){ // 指定两个 |
|
$query->havingBetween($field, [$min, $max]); |
|
|
|
return $query; |
|
} |
|
|
|
if (!empty($min)) { |
|
$query->having($field, '>' . $eq, $min); |
|
} |
|
if (!empty($max)) { |
|
$query->having($field, '<' . $eq, $max); |
|
} |
|
|
|
return $query; |
|
} |
|
|
|
/** |
|
* 分页,和系统paginate一样,增加$countRaw可以控制count的字段 |
|
* |
|
* @param Builder|QueryBuilder $query |
|
* @param int $perPage |
|
* @param string $countRaw count统计字段默认aggregate别名 |
|
* @param array $columns |
|
* @param string $pageName |
|
* @param int|null $page |
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator |
|
*/ |
|
public function scopePaginateRaw($query, $perPage = 15, $countRaw = 'count(*) as aggregate', $columns = ['*'], $pageName = 'page', $page = null) |
|
{ |
|
$page = $page ?: Paginator::resolveCurrentPage($pageName); |
|
|
|
// count统计 |
|
/** @var Builder $total */ |
|
$total = (clone $query)->select([])->forPage(1, 1)->selectRaw($countRaw); |
|
$total->getQuery()->orders = null; // 清空数据 |
|
$total = $total->first(); |
|
$total = intval($total['aggregate'] ?? 0); // 默认aggregate别名 |
|
|
|
$results = $total ? $query->forPage($page, $perPage)->get($columns) : []; |
|
|
|
// 这个对象可以直接foreach,拿到model |
|
return new LengthAwarePaginator($results, $total, $perPage, $page, [ |
|
'path' => Paginator::resolveCurrentPath(), |
|
'pageName' => $pageName, |
|
]); |
|
} |
|
} |