|
|
@@ -0,0 +1,131 @@
|
|
|
+import React from 'react';
|
|
|
+import {
|
|
|
+ Pagination,
|
|
|
+ PaginationContent,
|
|
|
+ PaginationEllipsis,
|
|
|
+ PaginationItem,
|
|
|
+ PaginationLink,
|
|
|
+ PaginationNext,
|
|
|
+ PaginationPrevious,
|
|
|
+} from '@/client/components/ui/pagination';
|
|
|
+
|
|
|
+interface DataTablePaginationProps {
|
|
|
+ currentPage: number;
|
|
|
+ totalCount: number;
|
|
|
+ pageSize: number;
|
|
|
+ onPageChange: (page: number, pageSize: number) => void;
|
|
|
+}
|
|
|
+
|
|
|
+export const DataTablePagination: React.FC<DataTablePaginationProps> = ({
|
|
|
+ currentPage,
|
|
|
+ totalCount,
|
|
|
+ pageSize,
|
|
|
+ onPageChange,
|
|
|
+}) => {
|
|
|
+ const totalPages = Math.ceil(totalCount / pageSize);
|
|
|
+
|
|
|
+ const getPageNumbers = () => {
|
|
|
+ const pages = [];
|
|
|
+
|
|
|
+ if (totalPages <= 7) {
|
|
|
+ // 如果总页数小于等于7,显示所有页码
|
|
|
+ for (let i = 1; i <= totalPages; i++) {
|
|
|
+ pages.push(i);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // 显示当前页附近的页码
|
|
|
+ const startPage = Math.max(1, currentPage - 2);
|
|
|
+ const endPage = Math.min(totalPages, currentPage + 2);
|
|
|
+
|
|
|
+ // 始终显示第一页
|
|
|
+ pages.push(1);
|
|
|
+
|
|
|
+ // 添加省略号和中间页码
|
|
|
+ if (startPage > 2) {
|
|
|
+ pages.push('...');
|
|
|
+ }
|
|
|
+
|
|
|
+ for (let i = Math.max(2, startPage); i <= Math.min(totalPages - 1, endPage); i++) {
|
|
|
+ pages.push(i);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (endPage < totalPages - 1) {
|
|
|
+ pages.push('...');
|
|
|
+ }
|
|
|
+
|
|
|
+ // 始终显示最后一页
|
|
|
+ pages.push(totalPages);
|
|
|
+ }
|
|
|
+
|
|
|
+ return pages;
|
|
|
+ };
|
|
|
+
|
|
|
+ const pageNumbers = getPageNumbers();
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className="flex justify-between items-center mt-4">
|
|
|
+ <div className="text-sm text-muted-foreground">
|
|
|
+ 第 {currentPage} 页,共 {totalPages} 页,共 {totalCount} 条记录
|
|
|
+ </div>
|
|
|
+ <Pagination>
|
|
|
+ <PaginationContent>
|
|
|
+ <PaginationItem>
|
|
|
+ <PaginationPrevious
|
|
|
+ href="#"
|
|
|
+ onClick={(e) => {
|
|
|
+ e.preventDefault();
|
|
|
+ if (currentPage > 1) {
|
|
|
+ onPageChange(currentPage - 1, pageSize);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ aria-disabled={currentPage <= 1}
|
|
|
+ className={currentPage <= 1 ? "pointer-events-none opacity-50" : ""}
|
|
|
+ >
|
|
|
+ 上一页
|
|
|
+ </PaginationPrevious>
|
|
|
+ </PaginationItem>
|
|
|
+
|
|
|
+ {pageNumbers.map((page, index) => {
|
|
|
+ if (page === '...') {
|
|
|
+ return (
|
|
|
+ <PaginationItem key={`ellipsis-${index}`}>
|
|
|
+ <PaginationEllipsis />
|
|
|
+ </PaginationItem>
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return (
|
|
|
+ <PaginationItem key={page}>
|
|
|
+ <PaginationLink
|
|
|
+ href="#"
|
|
|
+ isActive={page === currentPage}
|
|
|
+ onClick={(e) => {
|
|
|
+ e.preventDefault();
|
|
|
+ onPageChange(page as number, pageSize);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {page}
|
|
|
+ </PaginationLink>
|
|
|
+ </PaginationItem>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+
|
|
|
+ <PaginationItem>
|
|
|
+ <PaginationNext
|
|
|
+ href="#"
|
|
|
+ onClick={(e) => {
|
|
|
+ e.preventDefault();
|
|
|
+ if (currentPage < totalPages) {
|
|
|
+ onPageChange(currentPage + 1, pageSize);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ aria-disabled={currentPage >= totalPages}
|
|
|
+ className={currentPage >= totalPages ? "pointer-events-none opacity-50" : ""}
|
|
|
+ >
|
|
|
+ 下一页
|
|
|
+ </PaginationNext>
|
|
|
+ </PaginationItem>
|
|
|
+ </PaginationContent>
|
|
|
+ </Pagination>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+};
|