You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
5.3 KiB
PHTML
212 lines
5.3 KiB
PHTML
2 years ago
|
<?php
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace App\Helper;
|
||
|
|
||
|
use Hyperf\Database\Model\Collection;
|
||
|
use Hyperf\Database\Query\Builder;
|
||
|
use Hyperf\DbConnection\Db as DB;
|
||
|
|
||
|
class DataList implements Logic
|
||
|
{
|
||
|
public $name;
|
||
|
|
||
|
protected $params;
|
||
|
protected $page;
|
||
|
protected $limit;
|
||
|
protected $offset;
|
||
|
protected $pagination;
|
||
|
protected $records = [];
|
||
|
protected $isGroupQuery = false;
|
||
|
protected $withoutPaginate = false;
|
||
|
protected $isQuickPaginate = false;
|
||
|
protected $isSpanRow = false;
|
||
|
|
||
|
/**
|
||
|
* @param array $params 查询数据
|
||
|
*/
|
||
|
public function __construct(array $params = [])
|
||
|
{
|
||
|
$this->params = $params;
|
||
|
$this->check();
|
||
|
$this->init();
|
||
|
}
|
||
|
|
||
|
protected function init()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
protected function beforeGenerate($items)
|
||
|
{
|
||
|
return $items;
|
||
|
}
|
||
|
|
||
|
protected function afterGenerate()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
public function generateRecords($items)
|
||
|
{
|
||
|
$items = $this->beforeGenerate($items);
|
||
|
$this->records = [];
|
||
|
if ($this->isSpanRow) {
|
||
|
foreach ($items as $item) {
|
||
|
$this->records = array_merge($this->records, $this->toArray($item));
|
||
|
}
|
||
|
} else {
|
||
|
foreach ($items as $item) {
|
||
|
$this->records[] = $this->toArray($item);
|
||
|
}
|
||
|
}
|
||
|
$this->afterGenerate();
|
||
|
}
|
||
|
|
||
|
public function toArray($item)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public function query()
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
protected function statOffset($page, $limit)
|
||
|
{
|
||
|
return ($page - 1) * $limit;
|
||
|
}
|
||
|
|
||
|
public function paginate(): DataList
|
||
|
{
|
||
|
[$records, $pagination] = $this->doPaginate();
|
||
|
$this->pagination = $pagination;
|
||
|
$this->generateRecords($records);
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function doPaginate(): array
|
||
|
{
|
||
|
$count = 0;
|
||
|
$this->page = $page = intval($this->params['page'] ?? 1);
|
||
|
$this->limit = $limit = intval($this->params['limit'] ?? 10);
|
||
|
$this->offset = $offset = $this->statOffset($page, $limit);
|
||
|
|
||
|
$records = new Collection([]);
|
||
|
$query = $this->query();
|
||
|
if (is_null($query)) {
|
||
|
$pagination = $this->generatePagination($page, $limit, $this->getCount());
|
||
|
return [$records, $pagination];
|
||
|
}
|
||
|
|
||
|
if ($this->withoutPaginate) {
|
||
|
$searchQuery = clone $query;
|
||
|
return [$searchQuery->get(), null];
|
||
|
}
|
||
|
|
||
|
// 临时快速分页
|
||
|
if ($this->isQuickPaginate) {
|
||
|
return $this->quickPaginate(clone $query, $page, $limit);
|
||
|
} else {
|
||
|
$count = $this->getCount();
|
||
|
if ($count) {
|
||
|
$searchQuery = clone $query;
|
||
|
$records = $searchQuery->offset($offset)->limit($limit)->get();
|
||
|
}
|
||
|
$pagination = $this->generatePagination($page, $limit, $count);
|
||
|
}
|
||
|
return [$records, $pagination];
|
||
|
}
|
||
|
|
||
|
protected function quickPaginate($query, $page, $limit)
|
||
|
{
|
||
|
$count = 1;
|
||
|
$offset = $this->statOffset($page, $limit);
|
||
|
$records = $query->offset($offset)->limit($limit+1)->get();
|
||
|
$recordCount = $records->count();
|
||
|
if ($recordCount < $limit+1) {
|
||
|
$hasMroe = false;
|
||
|
} else {
|
||
|
$records->pop();
|
||
|
$hasMroe = true;
|
||
|
}
|
||
|
$pagination = $this->generatePagination($page, $limit, $count, $hasMroe);
|
||
|
return [$records, $pagination];
|
||
|
}
|
||
|
|
||
|
protected function generatePagination($page, $limit, $count, $hasMroe = false)
|
||
|
{
|
||
|
$pageCount = intval(ceil($count/$limit));
|
||
|
if (! $hasMroe) {
|
||
|
if ($page < $pageCount) {
|
||
|
$hasMroe = true;
|
||
|
}
|
||
|
}
|
||
|
return [
|
||
|
'page' => $page,
|
||
|
'count' => $count,
|
||
|
'page_count' => $pageCount,
|
||
|
'limit' => $limit,
|
||
|
'has_more'=> $hasMroe,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
public function getCount()
|
||
|
{
|
||
|
$query = $this->query();
|
||
|
if (is_null($query)) {
|
||
|
return 0;
|
||
|
}
|
||
|
$countQuery = clone $query;
|
||
|
if ($this->isGroupQuery) {
|
||
|
$countQuery->select([DB::raw('1')]);
|
||
|
return DB::table(DB::raw("({$countQuery->toSql()}) as temp_count_table"))
|
||
|
->mergeBindings($query instanceof Builder ? $countQuery : $countQuery->getQuery())
|
||
|
->count();
|
||
|
} else {
|
||
|
return $countQuery->count();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function getPagination(): ?array
|
||
|
{
|
||
|
return $this->pagination;
|
||
|
}
|
||
|
|
||
|
public function setWithoutPaginate($withoutPaginate)
|
||
|
{
|
||
|
$this->withoutPaginate = $withoutPaginate;
|
||
|
return $this;
|
||
|
}
|
||
|
|
||
|
public function getRecords()
|
||
|
{
|
||
|
return $this->records;
|
||
|
}
|
||
|
|
||
|
public function getSummary()
|
||
|
{
|
||
|
return [];
|
||
|
}
|
||
|
|
||
|
public function check()
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 获取 记录(records)/分页(pagination)/汇总(summary)
|
||
|
* @param array $appendOptions 追加信息一起返回
|
||
|
* @return array
|
||
|
*/
|
||
|
public function all($appendOptions = [])
|
||
|
{
|
||
|
$data = [
|
||
|
'records' => $this->getRecords(),
|
||
|
'pagination' => $this->getPagination(),
|
||
|
'summary' => $this->getSummary(),
|
||
|
];
|
||
|
return array_merge($data, $appendOptions);
|
||
|
}
|
||
|
}
|