// ==================== 渲染函数 ==================== function renderFullData(apiResponse, source) { if (!apiResponse) { const div = document.createElement('div'); div.className = 'no-data'; div.textContent = '【200条数据】暂无数据,请先点击MEXC或Binance按钮获取K线数据。'; return div; } const symbols = sortSymbols(Object.keys(apiResponse)); const cardTemplate = document.getElementById('template-symbol-card'); const periodTemplate = document.getElementById('template-period-table'); if (!cardTemplate || !periodTemplate) { const errorDiv = document.createElement('div'); errorDiv.className = 'no-data'; errorDiv.textContent = '❌ 渲染模板缺失,请检查 HTML 中的 template 元素'; return errorDiv; } const fragment = document.createDocumentFragment(); for (let sym of symbols) { const intervals = apiResponse[sym]; if (!intervals) continue; const card = cardTemplate.content.cloneNode(true); card.querySelector('.symbol-name').textContent = sym; const sourceName = source === 'mexc' ? 'MEXC REST API' : 'Binance Public API'; card.querySelector('.symbol-badge').textContent = sourceName; const periodsContainer = card.querySelector('.periods-container'); for (let period of ['5m','1h','4h','15m']) { const kdata = intervals[period]; if (!kdata || kdata.error) { const errMsg = kdata?.error || '无数据'; const errorDiv = document.createElement('div'); errorDiv.className = 'error-msg'; errorDiv.textContent = `⚠️ ${period} 错误: ${errMsg}`; periodsContainer.appendChild(errorDiv); continue; } if (!Array.isArray(kdata) || kdata.length===0) { const emptyDiv = document.createElement('div'); emptyDiv.className = 'error-msg'; emptyDiv.textContent = `📭 ${period} 空数据`; periodsContainer.appendChild(emptyDiv); continue; } const sorted = [...kdata].reverse(); const periodClone = periodTemplate.content.cloneNode(true); const tbody = periodClone.querySelector('tbody'); // 在填充数据之前或之后,修改第一个 th 的内容 const firstTh = periodClone.querySelector('thead tr th:first-child'); if (firstTh) { firstTh.textContent = `开盘时间 【周期:${period}】`; } for (let k of sorted) { if (!Array.isArray(k) || k.length<8) continue; const row = document.createElement('tr'); row.innerHTML = ` ${formatTimestamp(k[0])} ${formatPrice(k[1])} ${formatPrice(k[2])} ${formatPrice(k[3])} ${formatPrice(k[4])} ${formatPrice(k[5])} ${formatTimestamp(k[6])} ${formatPrice(k[7])} `; tbody.appendChild(row); } const footer = periodClone.querySelector('.period-footer'); footer.textContent = `📍 共 ${sorted.length} 条K线 (最新在上) | 周期: ${period} | limit=200`; periodsContainer.appendChild(periodClone); } fragment.appendChild(card); } const container = document.createElement('div'); container.appendChild(fragment); return container; } function renderCurrentData(apiResponse, source) { if (!apiResponse) { const div = document.createElement('div'); div.className = 'no-data'; div.textContent = '【当前数据】暂无数据,请先点击MEXC或Binance按钮获取K线数据。'; return div; } const symbols = sortSymbols(Object.keys(apiResponse)); const rowsData = []; for (let sym of symbols) { let intervals = apiResponse[sym]; if (!intervals) continue; const period = '5m'; let kdata = intervals[period]; if (!kdata || kdata.error || !Array.isArray(kdata) || kdata.length===0) continue; const latest = kdata[kdata.length-1]; if (!latest || latest.length<8) continue; rowsData.push({ symbol: sym, openTime: latest[0], open: latest[1], high: latest[2], low: latest[3], close: latest[4], volume: latest[5], closeTime: latest[6], quoteVolume: latest[7] }); } if (rowsData.length === 0) { const div = document.createElement('div'); div.className = 'no-data'; div.textContent = '没有有效的5m最新数据'; return div; } const sourceName = source === 'mexc' ? 'MEXC REST API' : 'Binance Public API'; const template = document.getElementById('template-current-table'); if (!template) { const errorDiv = document.createElement('div'); errorDiv.className = 'no-data'; errorDiv.textContent = '❌ 当前数据模板缺失'; return errorDiv; } const clone = template.content.cloneNode(true); clone.querySelector('.table-caption').textContent = `${sourceName} · 5m (最新1条)`; const tbody = clone.querySelector('tbody'); for (let row of rowsData) { const tr = document.createElement('tr'); tr.innerHTML = ` ${formatTimestamp(row.openTime)} ${row.symbol} ${formatPrice(row.open)} ${formatPrice(row.high)} ${formatPrice(row.low)} ${formatPrice(row.close)} ${formatPrice(row.volume)} ${formatTimestamp(row.closeTime)} ${formatPrice(row.quoteVolume)} `; tbody.appendChild(tr); } const container = document.createElement('div'); container.appendChild(clone); const copyBtn = container.querySelector('.copy-table-btn'); if (copyBtn) copyBtn.id = 'copyCurrentTableBtn'; return container; }