const WeatherTable = { display(historyData = [], forecastData = []) { historyData = Array.isArray(historyData) ? historyData : []; forecastData = Array.isArray(forecastData) ? forecastData : []; if (historyData.length === 0 && forecastData.length === 0) { return; } const showPastEl = document.getElementById('showPastForecast'); const endInput = document.getElementById('endDate')?.value; let endTs = Date.now(); if (endInput) { const d = new Date(endInput); if (!isNaN(d)) endTs = d.getTime(); } const future3hTs = endTs + 3 * 60 * 60 * 1000; const showPast = !!(showPastEl && showPastEl.checked); const displayedForecast = forecastData.filter(item => { const t = new Date(item.date_time).getTime(); const isFuture3h = t > endTs && t <= future3hTs; const isPast = t <= endTs; return isFuture3h || (showPast && isPast); }); const taggedHistory = historyData.map(item => ({ ...item, __source: '实测' })); const taggedForecast = displayedForecast.map(item => ({ ...item, __source: '预报' })); const allData = [...taggedHistory, ...taggedForecast]; const hasForecast = taggedForecast.length > 0; const sortedData = allData.sort((a, b) => new Date(b.date_time) - new Date(a.date_time)); const tableBody = document.getElementById('tableBody'); if (!tableBody) return; tableBody.innerHTML = ''; // 动态表头:在有预报时加入“降水概率 (%)” const headerRow = document.getElementById('tableHeader'); if (headerRow) { headerRow.innerHTML = ''; const addTh = (text) => { const th = document.createElement('th'); th.textContent = text; headerRow.appendChild(th); }; ['时间','温度 (°C)','湿度 (%)','气压 (hPa)','风速 (m/s)','风向 (°)','雨量 (mm)'].forEach(addTh); if (hasForecast) addTh('降水概率 (%)'); ['光照 (lux)','紫外线'].forEach(addTh); } const fmt = (v, digits) => (v === null || v === undefined || v === '' || isNaN(Number(v))) ? '' : Number(v).toFixed(digits); sortedData.forEach(row => { const tr = document.createElement('tr'); const isForecast = row.__source === '预报'; if (isForecast) { tr.style.backgroundColor = 'rgba(255, 165, 0, 0.08)'; } const issuedBadge = (() => { if (!isForecast) return ''; const lead = (typeof row.lead_hours === 'number' && row.lead_hours >= 0) ? ` +${row.lead_hours}h` : ''; const issued = row.issued_at ? new Date(String(row.issued_at).replace(' ', 'T')) : null; const issuedStr = issued ? `${String(issued.getHours()).padStart(2,'0')}:${String(issued.getMinutes()).padStart(2,'0')}` : '-'; return `(发布: ${issuedStr}${lead})`; })(); const timeCell = `${row.date_time || ''}${isForecast ? ' [预报]' : ''}${isForecast ? `
${issuedBadge}` : ''}`; const columns = [ `${timeCell}`, `${fmt(row.temperature, 1)}`, `${fmt(row.humidity, 1)}`, `${fmt(row.pressure, 1)}`, `${fmt(row.wind_speed, 1)}`, `${fmt(row.wind_direction, 0)}`, `${fmt(row.rainfall, 2)}` ]; if (hasForecast) { const val = isForecast && row.precip_prob !== null && row.precip_prob !== undefined ? row.precip_prob : '-'; columns.push(`${val}`); } columns.push( `${fmt(row.light, 0)}`, `${fmt(row.uv, 1)}` ); tr.innerHTML = columns.join(''); tableBody.appendChild(tr); }); const forecastToggleContainer = document.getElementById('forecastToggleContainer'); if (forecastToggleContainer) { forecastToggleContainer.style.display = forecastData.length > 0 ? 'flex' : 'none'; } } }; window.WeatherTable = WeatherTable;