diff --git a/src/components/Pagination.css b/src/components/Pagination.css new file mode 100644 index 0000000..54cd2e7 --- /dev/null +++ b/src/components/Pagination.css @@ -0,0 +1,120 @@ +/* 自定义分页组件样式 */ +.custom-pagination { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 0; + border-top: 1px solid #f0f0f0; + background: #fafafa; + border-radius: 0 0 6px 6px; + margin: 0 -24px -24px -24px; + padding-left: 24px; + padding-right: 24px; +} + +.pagination-info { + display: flex; + align-items: center; + gap: 16px; + color: #666; + font-size: 14px; +} + +.pagination-controls { + display: flex; + align-items: center; + gap: 4px; +} + +.pagination-page-item { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + border: 1px solid #d9d9d9; + border-radius: 6px; + cursor: pointer; + margin: 0 2px; + font-size: 14px; + transition: all 0.2s ease; + background-color: #ffffff; + color: #333; +} + +.pagination-page-item:hover { + background-color: #e6f7ff; + border-color: #1890ff; + color: #1890ff; +} + +.pagination-page-item.active { + background-color: #1890ff; + color: #ffffff; + border-color: #1890ff; +} + +.pagination-page-item.active:hover { + background-color: #40a9ff; + border-color: #40a9ff; +} + +.pagination-page-item.disabled { + cursor: not-allowed; + color: #d9d9d9; + background-color: #f5f5f5; + border-color: #d9d9d9; +} + +.pagination-page-item.disabled:hover { + color: #d9d9d9; + background-color: #f5f5f5; + border-color: #d9d9d9; +} + +.pagination-ellipsis { + display: inline-flex; + align-items: center; + justify-content: center; + width: 32px; + height: 32px; + cursor: default; + border: none; + color: #999; +} + +.pagination-jumper { + display: flex; + align-items: center; + gap: 8px; + color: #666; + font-size: 14px; +} + +.pagination-page-info { + min-width: 80px; + text-align: right; + color: #666; + font-size: 14px; +} + +/* 响应式设计 */ +@media (max-width: 768px) { + .custom-pagination { + flex-direction: column; + gap: 16px; + align-items: stretch; + } + + .pagination-info { + justify-content: center; + } + + .pagination-controls { + justify-content: center; + } + + .pagination-jumper { + justify-content: center; + } +} \ No newline at end of file diff --git a/src/components/Pagination.js b/src/components/Pagination.js new file mode 100644 index 0000000..23027ad --- /dev/null +++ b/src/components/Pagination.js @@ -0,0 +1,210 @@ +/** + * 自定义分页组件 + * 支持页码跳转、页面大小选择等功能 + */ +import React from 'react'; +import { Select, Input, Button, Space, Typography } from 'antd'; +import './Pagination.css'; +import { + LeftOutlined, + RightOutlined, + DoubleLeftOutlined, + DoubleRightOutlined +} from '@ant-design/icons'; + +const { Option } = Select; +const { Text } = Typography; + +const Pagination = ({ + current = 1, + total = 0, + pageSize = 10, + showSizeChanger = true, + showQuickJumper = true, + showTotal = true, + onChange, + onShowSizeChange, + pageSizeOptions = ['10', '20', '50', '100'], + style = {} +}) => { + const totalPages = Math.ceil(total / pageSize); + + // 计算显示的页码范围 + const getVisiblePages = () => { + const pages = []; + const delta = 2; // 当前页前后显示的页数 + + if (totalPages <= 7) { + // 总页数较少时显示所有页码 + for (let i = 1; i <= totalPages; i++) { + pages.push(i); + } + } else { + // 总页数较多时显示部分页码 + let start = Math.max(1, current - delta); + let end = Math.min(totalPages, current + delta); + + if (current <= delta + 1) { + end = Math.min(totalPages, 2 * delta + 2); + } + + if (current >= totalPages - delta) { + start = Math.max(1, totalPages - 2 * delta - 1); + } + + if (start > 1) { + pages.push(1); + if (start > 2) { + pages.push('...'); + } + } + + for (let i = start; i <= end; i++) { + pages.push(i); + } + + if (end < totalPages) { + if (end < totalPages - 1) { + pages.push('...'); + } + pages.push(totalPages); + } + } + + return pages; + }; + + // 处理页码点击 + const handlePageClick = (page) => { + if (page !== current && page >= 1 && page <= totalPages) { + onChange?.(page, pageSize); + } + }; + + // 处理页面大小变化 + const handlePageSizeChange = (newPageSize) => { + const newCurrent = Math.min(current, Math.ceil(total / newPageSize)); + onShowSizeChange?.(newCurrent, newPageSize); + onChange?.(newCurrent, newPageSize); + }; + + // 处理快速跳转 + const handleQuickJump = (e) => { + if (e.key === 'Enter') { + const page = parseInt(e.target.value, 10); + if (page >= 1 && page <= totalPages) { + handlePageClick(page); + e.target.value = ''; + } + } + }; + + // 使用CSS类而不是内联样式 + + if (total === 0) return null; + + return ( +