class TransferUtils { static parseCSV(csvText) { const lines = csvText.split('\n'); const transfers = []; for (let i = 0; i < lines.length; i++) { const line = lines[i].trim(); if (!line) continue; // 支持逗号分隔或制表符分隔 const parts = line.includes('\t') ? line.split('\t') : line.split(','); if (parts.length >= 2) { const address = parts[0].trim(); const amount = parts[1].trim(); const note = parts[2] ? parts[2].trim() : ''; // 基本验证 if (address && amount) { transfers.push({ address, amount: parseFloat(amount), note }); } } } return transfers; } static formatAddress(address) { if (!address || address.length < 10) return address; return `${address.slice(0, 6)}...${address.slice(-4)}`; } static formatNumber(num, decimals = 4) { // 处理各种输入类型 if (num === null || num === undefined) return '0'; // 转换为数字 const numValue = typeof num === 'string' ? parseFloat(num) : Number(num); // 检查是否为有效数字 if (isNaN(numValue)) return '0'; // 格式化并返回 return parseFloat(numValue.toFixed(decimals)).toString(); } static generateLogMessage(type, message) { const time = new Date().toLocaleTimeString(); const types = { success: { icon: '✅', class: 'success' }, error: { icon: '❌', class: 'error' }, info: { icon: 'ℹ️', class: 'info' }, warning: { icon: '⚠️', class: 'warning' } }; const typeInfo = types[type] || types.info; return { time, type: typeInfo.class, message: `${typeInfo.icon} ${message}`, html: `
${time}
${typeInfo.icon} ${message}
` }; } static exportToCSV(data, filename = 'transfer-results.csv') { const headers = ['序号', '收款地址', '金额(BNB)', '状态', '交易哈希', '备注']; const rows = data.map(item => [ item.index + 1, item.to, item.amount, item.success ? '成功' : '失败', item.hash || '', item.error || '' ]); const csvContent = [headers, ...rows] .map(row => row.map(cell => `"${cell}"`).join(',')) .join('\n'); const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const link = document.createElement('a'); if (navigator.msSaveBlob) { navigator.msSaveBlob(blob, filename); } else { link.href = URL.createObjectURL(blob); link.download = filename; link.style.display = 'none'; document.body.appendChild(link); link.click(); document.body.removeChild(link); } } static validateEthereumAddress(address) { try { return ethers.utils.isAddress(address); } catch { return false; } } static async checkBalanceSufficient(provider, address, requiredAmount) { try { const balance = await provider.getBalance(address); const required = ethers.utils.parseEther(requiredAmount.toString()); return balance.gte(required); } catch (error) { console.error('检查余额失败:', error); return false; } } } // 导出工具类 window.TransferUtils = TransferUtils;