DataTablePagination.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import React from 'react';
  2. import {
  3. Pagination,
  4. PaginationContent,
  5. PaginationEllipsis,
  6. PaginationItem,
  7. PaginationLink,
  8. PaginationNext,
  9. PaginationPrevious,
  10. } from '@/client/components/ui/pagination';
  11. interface DataTablePaginationProps {
  12. currentPage: number;
  13. totalCount: number;
  14. pageSize: number;
  15. onPageChange: (page: number, pageSize: number) => void;
  16. }
  17. export const DataTablePagination: React.FC<DataTablePaginationProps> = ({
  18. currentPage,
  19. totalCount,
  20. pageSize,
  21. onPageChange,
  22. }) => {
  23. const totalPages = Math.ceil(totalCount / pageSize);
  24. const getPageNumbers = () => {
  25. const pages = [];
  26. if (totalPages <= 7) {
  27. // 如果总页数小于等于7,显示所有页码
  28. for (let i = 1; i <= totalPages; i++) {
  29. pages.push(i);
  30. }
  31. } else {
  32. // 显示当前页附近的页码
  33. const startPage = Math.max(1, currentPage - 2);
  34. const endPage = Math.min(totalPages, currentPage + 2);
  35. // 始终显示第一页
  36. pages.push(1);
  37. // 添加省略号和中间页码
  38. if (startPage > 2) {
  39. pages.push('...');
  40. }
  41. for (let i = Math.max(2, startPage); i <= Math.min(totalPages - 1, endPage); i++) {
  42. pages.push(i);
  43. }
  44. if (endPage < totalPages - 1) {
  45. pages.push('...');
  46. }
  47. // 始终显示最后一页
  48. pages.push(totalPages);
  49. }
  50. return pages;
  51. };
  52. const pageNumbers = getPageNumbers();
  53. return (
  54. <div className="flex justify-between items-center mt-4">
  55. <Pagination>
  56. <PaginationContent>
  57. <PaginationItem>
  58. <PaginationPrevious
  59. href="#"
  60. onClick={(e) => {
  61. e.preventDefault();
  62. if (currentPage > 1) {
  63. onPageChange(currentPage - 1, pageSize);
  64. }
  65. }}
  66. aria-disabled={currentPage <= 1}
  67. className={currentPage <= 1 ? "pointer-events-none opacity-50" : ""}
  68. />
  69. </PaginationItem>
  70. {pageNumbers.map((page, index) => {
  71. if (page === '...') {
  72. return (
  73. <PaginationItem key={`ellipsis-${index}`}>
  74. <PaginationEllipsis />
  75. </PaginationItem>
  76. );
  77. }
  78. return (
  79. <PaginationItem key={page}>
  80. <PaginationLink
  81. href="#"
  82. isActive={page === currentPage}
  83. onClick={(e) => {
  84. e.preventDefault();
  85. onPageChange(page as number, pageSize);
  86. }}
  87. >
  88. {page}
  89. </PaginationLink>
  90. </PaginationItem>
  91. );
  92. })}
  93. <PaginationItem>
  94. <PaginationNext
  95. href="#"
  96. onClick={(e) => {
  97. e.preventDefault();
  98. if (currentPage < totalPages) {
  99. onPageChange(currentPage + 1, pageSize);
  100. }
  101. }}
  102. aria-disabled={currentPage >= totalPages}
  103. className={currentPage >= totalPages ? "pointer-events-none opacity-50" : ""}
  104. />
  105. </PaginationItem>
  106. </PaginationContent>
  107. </Pagination>
  108. </div>
  109. );
  110. };