| import React, { useState, useEffect } from 'react'; |
| import { fetchRecordLog } from '../api/posts_trm'; |
| |
| function TransactionLogs({ userId }) { |
| const [allRecords, setAllRecords] = useState([]); |
| const [currentPage, setCurrentPage] = useState(1); |
| const [pageSize] = useState(10); |
| const [loading, setLoading] = useState(false); |
| |
| const loadRecords = async () => { |
| setLoading(true); |
| try { |
| const data = await fetchRecordLog(); |
| setAllRecords(data); |
| } catch (err) { |
| console.error('fetchRecordLog error:', err); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| useEffect(() => { |
| loadRecords(); |
| }, [userId]); |
| |
| const total = allRecords.length; |
| const totalPages = Math.ceil(total / pageSize); |
| |
| // 计算当前页显示的数据 |
| const startIndex = (currentPage - 1) * pageSize; |
| const endIndex = startIndex + pageSize; |
| const currentRecords = allRecords.slice(startIndex, endIndex); |
| |
| const handlePrevPage = () => { |
| if (currentPage > 1) { |
| setCurrentPage(currentPage - 1); |
| } |
| }; |
| |
| const handleNextPage = () => { |
| if (currentPage < totalPages) { |
| setCurrentPage(currentPage + 1); |
| } |
| }; |
| |
| const handlePageClick = (page) => { |
| setCurrentPage(page); |
| }; |
| |
| const renderPageNumbers = () => { |
| const pages = []; |
| const maxVisiblePages = 5; |
| |
| let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2)); |
| let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1); |
| |
| if (endPage - startPage < maxVisiblePages - 1) { |
| startPage = Math.max(1, endPage - maxVisiblePages + 1); |
| } |
| |
| for (let i = startPage; i <= endPage; i++) { |
| pages.push( |
| <button |
| key={i} |
| onClick={() => handlePageClick(i)} |
| className={`page-btn ${currentPage === i ? 'active' : ''}`} |
| > |
| {i} |
| </button> |
| ); |
| } |
| return pages; |
| }; |
| |
| return ( |
| <section className="dashboard-logs"> |
| <table className="admin-table"> |
| <thead> |
| <tr> |
| <th>ID</th> |
| <th>用户ID</th> |
| <th>类型</th> |
| <th>内容</th> |
| <th>IP</th> |
| <th>创建时间</th> |
| </tr> |
| </thead> |
| <tbody> |
| {loading ? ( |
| <tr> |
| <td colSpan="6" style={{ textAlign: 'center' }}>加载中...</td> |
| </tr> |
| ) : currentRecords.length > 0 ? ( |
| currentRecords.map((r, i) => ( |
| <tr key={r.id || i}> |
| <td>{r.id}</td> |
| <td>{r.user_id}</td> |
| <td>{r.type}</td> |
| <td>{r.content}</td> |
| <td>{r.ip}</td> |
| <td>{new Date(r.created_at).toLocaleString()}</td> |
| </tr> |
| )) |
| ) : ( |
| <tr> |
| <td colSpan="6" style={{ textAlign: 'center' }}>暂无数据</td> |
| </tr> |
| )} |
| </tbody> |
| </table> |
| |
| {totalPages > 1 && ( |
| <div className="pagination"> |
| <button |
| onClick={handlePrevPage} |
| disabled={currentPage === 1} |
| className="page-btn" |
| > |
| 上一页 |
| </button> |
| |
| {renderPageNumbers()} |
| |
| <button |
| onClick={handleNextPage} |
| disabled={currentPage === totalPages} |
| className="page-btn" |
| > |
| 下一页 |
| </button> |
| |
| <span className="page-info"> |
| 第 {currentPage} 页,共 {totalPages} 页,总计 {total} 条记录 |
| </span> |
| </div> |
| )} |
| |
| <style jsx>{` |
| .pagination { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| gap: 8px; |
| margin-top: 16px; |
| flex-wrap: wrap; |
| } |
| |
| .page-btn { |
| padding: 6px 12px; |
| border: 1px solid #ddd; |
| background: white; |
| cursor: pointer; |
| border-radius: 4px; |
| transition: all 0.2s; |
| } |
| |
| .page-btn:hover:not(:disabled) { |
| background: #f5f5f5; |
| border-color: #999; |
| } |
| |
| .page-btn:disabled { |
| opacity: 0.5; |
| cursor: not-allowed; |
| } |
| |
| .page-btn.active { |
| background: #007bff; |
| color: white; |
| border-color: #007bff; |
| } |
| |
| .page-info { |
| margin-left: 16px; |
| font-size: 14px; |
| color: #666; |
| } |
| `}</style> |
| </section> |
| ); |
| } |
| |
| export default TransactionLogs; |