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); } }