// 转账历史管理 class TransferHistory { constructor() { this.storageKey = 'bsc_transfer_history'; this.history = this.loadHistory(); this.filteredHistory = [...this.history]; this.initElements(); this.bindEvents(); this.render(); } initElements() { // 筛选器 this.statusFilter = document.getElementById('statusFilter'); this.typeFilter = document.getElementById('typeFilter'); this.searchInput = document.getElementById('searchInput'); // 操作按钮 this.exportBtn = document.getElementById('exportHistory'); this.clearBtn = document.getElementById('clearHistory'); // 统计 this.totalSuccess = document.getElementById('totalSuccess'); this.totalFailed = document.getElementById('totalFailed'); this.totalPending = document.getElementById('totalPending'); this.totalTransfers = document.getElementById('totalTransfers'); this.recordCount = document.getElementById('recordCount'); // 表格 this.tableBody = document.getElementById('historyTableBody'); // 模态框 this.detailModal = document.getElementById('detailModal'); this.closeDetailBtn = document.getElementById('closeDetail'); this.viewOnBscscanBtn = document.getElementById('viewOnBscscan'); } bindEvents() { // 筛选器事件 this.statusFilter.addEventListener('change', () => this.applyFilters()); this.typeFilter.addEventListener('change', () => this.applyFilters()); this.searchInput.addEventListener('input', () => this.applyFilters()); // 操作按钮 this.exportBtn.addEventListener('click', () => this.exportToCSV()); this.clearBtn.addEventListener('click', () => this.clearHistory()); // 模态框 this.closeDetailBtn.addEventListener('click', () => this.closeModal()); this.detailModal.querySelector('.modal-close').addEventListener('click', () => this.closeModal()); this.detailModal.addEventListener('click', (e) => { if (e.target === this.detailModal) this.closeModal(); }); } // 从localStorage加载历史记录 loadHistory() { try { const data = localStorage.getItem(this.storageKey); return data ? JSON.parse(data) : []; } catch (error) { console.error('加载历史记录失败:', error); return []; } } // 保存历史记录到localStorage saveHistory() { try { localStorage.setItem(this.storageKey, JSON.stringify(this.history)); } catch (error) { console.error('保存历史记录失败:', error); showNotification('保存失败', 'error'); } } // 应用筛选 applyFilters() { const status = this.statusFilter.value; const type = this.typeFilter.value; const search = this.searchInput.value.toLowerCase().trim(); this.filteredHistory = this.history.filter(record => { // 状态筛选 if (status !== 'all' && record.status !== status) return false; // 类型筛选 if (type !== 'all' && record.type !== type) return false; // 搜索筛选 if (search) { const searchableText = [ record.address, record.txHash, record.note ].join(' ').toLowerCase(); if (!searchableText.includes(search)) return false; } return true; }); this.render(); } // 渲染页面 render() { this.renderStats(); this.renderTable(); } // 渲染统计数据 renderStats() { const stats = { success: 0, failed: 0, pending: 0, total: this.history.length }; this.history.forEach(record => { if (record.status === 'success') stats.success++; else if (record.status === 'failed') stats.failed++; else if (record.status === 'pending') stats.pending++; }); this.totalSuccess.textContent = stats.success; this.totalFailed.textContent = stats.failed; this.totalPending.textContent = stats.pending; this.totalTransfers.textContent = stats.total; this.recordCount.textContent = this.filteredHistory.length; } // 渲染表格 renderTable() { if (this.filteredHistory.length === 0) { this.tableBody.innerHTML = `

${this.history.length === 0 ? '暂无转账记录' : '没有符合条件的记录'}

`; return; } // 按时间倒序排列 const sortedHistory = [...this.filteredHistory].sort((a, b) => b.timestamp - a.timestamp); this.tableBody.innerHTML = sortedHistory.map(record => ` ${this.formatTime(record.timestamp)} ${record.type === 'bnb' ? 'BNB' : record.tokenSymbol || 'Token'} ${this.formatAddress(record.address)} ${record.amount} ${record.type === 'bnb' ? 'BNB' : record.tokenSymbol || ''} ${this.getStatusText(record.status)} ${record.txHash ? ` ${this.formatTxHash(record.txHash)} ` : '-'} ${record.note || '-'} `).join(''); } // 显示详情模态框 showDetail(recordId) { const record = this.history.find(r => r.id === recordId); if (!record) return; document.getElementById('detailTime').textContent = this.formatTime(record.timestamp, true); document.getElementById('detailType').textContent = record.type === 'bnb' ? 'BNB' : `${record.tokenSymbol || 'Token'} (${record.tokenAddress})`; document.getElementById('detailAddress').textContent = record.address; document.getElementById('detailAmount').textContent = `${record.amount} ${record.type === 'bnb' ? 'BNB' : record.tokenSymbol || ''}`; document.getElementById('detailStatus').innerHTML = `${this.getStatusText(record.status)}`; document.getElementById('detailTxHash').textContent = record.txHash || '-'; document.getElementById('detailNote').textContent = record.note || '-'; document.getElementById('detailGas').textContent = record.gasCost ? `${record.gasCost} BNB` : '-'; if (record.txHash) { this.viewOnBscscanBtn.href = `https://bscscan.com/tx/${record.txHash}`; this.viewOnBscscanBtn.style.display = 'inline-flex'; } else { this.viewOnBscscanBtn.style.display = 'none'; } this.detailModal.style.display = 'flex'; } // 关闭模态框 closeModal() { this.detailModal.style.display = 'none'; } // 导出为CSV exportToCSV() { if (this.filteredHistory.length === 0) { showNotification('没有可导出的记录', 'warning'); return; } const headers = ['时间', '类型', '收款地址', '金额', '状态', '交易哈希', '备注', 'Gas费用']; const rows = this.filteredHistory.map(record => [ this.formatTime(record.timestamp, true), record.type === 'bnb' ? 'BNB' : record.tokenSymbol || 'Token', record.address, `${record.amount} ${record.type === 'bnb' ? 'BNB' : record.tokenSymbol || ''}`, this.getStatusText(record.status), record.txHash || '', record.note || '', record.gasCost || '' ]); const csvContent = [headers, ...rows] .map(row => row.map(cell => `"${cell}"`).join(',')) .join('\n'); const blob = new Blob(['\ufeff' + csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); link.href = URL.createObjectURL(blob); link.download = `transfer_history_${Date.now()}.csv`; link.click(); showNotification('导出成功', 'success'); } // 清空历史记录 clearHistory() { if (this.history.length === 0) { showNotification('没有可清空的记录', 'warning'); return; } if (!confirm('确定要清空所有历史记录吗?此操作不可恢复!')) { return; } this.history = []; this.filteredHistory = []; this.saveHistory(); this.render(); showNotification('历史记录已清空', 'success'); } // 格式化时间 formatTime(timestamp, full = false) { const date = new Date(timestamp); if (full) { return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' }); } return date.toLocaleString('zh-CN', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } // 格式化地址 formatAddress(address) { if (!address) return '-'; return `${address.slice(0, 6)}...${address.slice(-4)}`; } // 格式化交易哈希 formatTxHash(txHash) { if (!txHash) return '-'; return `${txHash.slice(0, 8)}...${txHash.slice(-6)}`; } // 获取状态文本 getStatusText(status) { const statusMap = { 'success': '成功', 'failed': '失败', 'pending': '待确认' }; return statusMap[status] || status; } } // 初始化 let historyManager; document.addEventListener('DOMContentLoaded', () => { historyManager = new TransferHistory(); // 将实例暴露到全局,供onclick使用 window.history = historyManager; });