class NewsApp { constructor() { this.newsContainer = document.getElementById('newsContainer'); this.loadingIndicator = document.getElementById('loadingIndicator'); this.endOfContent = document.getElementById('endOfContent'); this.startDateInput = document.getElementById('startDate'); this.endDateInput = document.getElementById('endDate'); this.refreshBtn = document.getElementById('refreshBtn'); this.currentStartDate = null; this.currentEndDate = null; this.isLoading = false; this.hasMoreNews = true; this.allNews = new Map(); // 用于存储所有新闻数据 this.init(); } init() { this.setupEventListeners(); this.initializeDates(); this.loadInitialNews(); this.setupInfiniteScroll(); } setupEventListeners() { // 刷新按钮点击事件 this.refreshBtn.addEventListener('click', () => { this.refreshNews(); }); // 日期输入变化事件 this.startDateInput.addEventListener('change', () => { this.updateDateRange(); }); this.endDateInput.addEventListener('change', () => { this.updateDateRange(); }); } initializeDates() { const today = new Date(); const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000); // 设置默认日期范围(最近一周) this.currentEndDate = this.formatDate(today); this.currentStartDate = this.formatDate(weekAgo); this.startDateInput.value = this.currentStartDate; this.endDateInput.value = this.currentEndDate; } formatDate(date) { return date.toISOString().split('T')[0]; } updateDateRange() { const newStartDate = this.startDateInput.value; const newEndDate = this.endDateInput.value; if (newStartDate && newEndDate) { if (new Date(newStartDate) > new Date(newEndDate)) { alert('开始日期不能晚于结束日期'); return; } this.currentStartDate = newStartDate; this.currentEndDate = newEndDate; this.refreshNews(); } } async loadInitialNews() { this.showLoading(true); try { const newsData = await this.fetchNews(this.currentStartDate, this.currentEndDate); this.renderNews(newsData); this.hasMoreNews = newsData.length > 0; } catch (error) { console.error('加载新闻失败:', error); this.showError('加载新闻失败,请稍后重试'); } finally { this.showLoading(false); } } async refreshNews() { this.allNews.clear(); this.newsContainer.innerHTML = ''; this.hasMoreNews = true; this.endOfContent.classList.add('hidden'); await this.loadInitialNews(); } async fetchNews(startDate, endDate) { // 显示加载状态 this.showLoading(true); try { // 构建API URL - 请替换为您的实际API地址 const apiUrl = `https://api.doorcome.cn/api/xwlbNews/?start_date=${startDate}&end_date=${endDate}`; console.log('Fetching news from:', apiUrl); // 调试日志 const response = await fetch(apiUrl, { method: 'GET', headers: { 'Content-Type': 'application/json', } }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const result = await response.json(); console.log('API Response:', result); // 调试日志 // 根据您的API返回格式调整 // 常见格式示例: // 1. { "data": { "news": [...] } } // 2. { "news": [...] } // 3. [...] // 直接是数组 if (result.data && result.data.news) { result.data.news.forEach(item => { if (item.news_improve) { item.news_improve = item.news_improve.replace(/\n/g, '
'); } }); return result.data.news; } else if (result.news) { return result.news; } else if (Array.isArray(result)) { return result; } else { console.error('无法识别的API返回格式:', result); return []; } } catch (error) { console.error('API调用失败:', error); this.showError('网络请求失败,请检查网络连接'); throw error; } finally { this.showLoading(false); } } renderNews(newsData) { // 按日期分组并排序 const groupedNews = this.groupNewsByDate(newsData); groupedNews.forEach((dayNews, date) => { // 如果该日期的新闻已经渲染过,则跳过 if (this.allNews.has(date)) { return; } this.allNews.set(date, dayNews); // 创建日期分组 const dateGroup = this.createDateGroup(date, dayNews); this.newsContainer.appendChild(dateGroup); // 添加淡入动画 anime({ targets: dateGroup, opacity: [0, 1], translateY: [20, 0], duration: 600, easing: 'easeOutQuart' }); }); } groupNewsByDate(newsData) { const grouped = new Map(); // 按日期分组 newsData.forEach(news => { const date = news.news_days; if (!grouped.has(date)) { grouped.set(date, []); } grouped.get(date).push(news); }); // 按日期倒序排列 const sortedGrouped = new Map(); const sortedDates = Array.from(grouped.keys()).sort((a, b) => new Date(b) - new Date(a)); sortedDates.forEach(date => { // 同一天的新闻按daily_sub_id排序 const dayNews = grouped.get(date).sort((a, b) => a.daily_sub_id - b.daily_sub_id); sortedGrouped.set(date, dayNews); }); return sortedGrouped; } createDateGroup(date, dayNews) { const dateGroup = document.createElement('div'); dateGroup.className = 'mb-8'; // 日期标题 const dateHeader = document.createElement('div'); dateHeader.className = 'mb-4'; dateHeader.innerHTML = `

${this.formatDisplayDate(date)}

`; dateGroup.appendChild(dateHeader); // 新闻列表 const newsList = document.createElement('div'); newsList.className = 'space-y-3'; dayNews.forEach((news, index) => { const newsItem = this.createNewsItem(news, index); newsList.appendChild(newsItem); }); dateGroup.appendChild(newsList); return dateGroup; } createNewsItem(news, index) { const newsItem = document.createElement('div'); newsItem.className = 'news-card bg-white rounded-lg shadow-sm border border-gray-200 p-4 cursor-pointer'; const newsId = `news-${news.news_days}-${news.daily_sub_id}`; newsItem.innerHTML = `

${news.news_title}

${this.formatDisplayDate(news.news_days)} ${news.daily_sub_id + 1}

${news.news_improve}

`; return newsItem; } formatDisplayDate(dateStr) { const date = new Date(dateStr); const today = new Date(); const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000); if (dateStr === this.formatDate(today)) { return '今天'; } else if (dateStr === this.formatDate(yesterday)) { return '昨天'; } else { return date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }); } } /* setupInfiniteScroll() { const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && !this.isLoading && this.hasMoreNews) { this.loadMoreNews(); } }); }, { rootMargin: '100px' }); // 观察加载指示器 observer.observe(this.loadingIndicator); }*/ setupInfiniteScroll() { const options = { root: null, // 使用视口作为根 rootMargin: '100px', // 提前100px开始加载 threshold: 0.1 // 元素10%可见时触发 }; const observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.isIntersecting && !this.isLoading && this.hasMoreNews) { console.log('触发滚动加载'); // 调试日志 this.loadMoreNews(); } }); }, options); // 创建一个触发元素,确保它始终在页面底部 const triggerElement = document.createElement('div'); triggerElement.id = 'scrollTrigger'; triggerElement.style.height = '1px'; triggerElement.style.marginTop = '100px'; document.body.appendChild(triggerElement); // 观察触发元素 observer.observe(triggerElement); // 同时观察加载指示器 observer.observe(this.loadingIndicator); } /* async loadMoreNews() { if (this.isLoading || !this.hasMoreNews) return; this.showLoading(true); try { // 找到当前最早的日期 const earliestDate = this.getEarliestDate(); if (!earliestDate) { this.hasMoreNews = false; return; } // 计算前一天的日期 const prevDate = new Date(earliestDate); prevDate.setDate(prevDate.getDate() - 1); const prevDateStr = this.formatDate(prevDate); // 加载前一天的新闻 const moreNews = await this.fetchNews(prevDateStr, prevDateStr); if (moreNews.length === 0) { this.hasMoreNews = false; this.endOfContent.classList.remove('hidden'); } else { this.renderNews(moreNews); } } catch (error) { console.error('加载更多新闻失败:', error); this.showError('加载更多新闻失败,请稍后重试'); } finally { this.showLoading(false); } } */ async loadMoreNews() { if (this.isLoading || !this.hasMoreNews) { console.log('跳过加载:isLoading=', this.isLoading, 'hasMoreNews=', this.hasMoreNews); return; } console.log('开始加载更多新闻...'); this.showLoading(true); try { // 找到当前最早的日期 const earliestDate = this.getEarliestDate(); if (!earliestDate) { console.log('没有找到最早日期'); this.hasMoreNews = false; return; } // 计算前一天的日期 const prevDate = new Date(earliestDate); prevDate.setDate(prevDate.getDate() - 1); const prevDateStr = this.formatDate(prevDate); console.log('加载日期:', prevDateStr); // 加载前一天的新闻 const moreNews = await this.fetchNews(prevDateStr, prevDateStr); console.log('加载到新闻数量:', moreNews.length); if (moreNews.length === 0) { this.hasMoreNews = false; this.endOfContent.classList.remove('hidden'); console.log('没有更多新闻了'); } else { this.renderNews(moreNews); this.hasMoreNews = true; } } catch (error) { console.error('加载更多新闻失败:', error); this.showError('加载更多新闻失败,请稍后重试'); } finally { this.showLoading(false); } } getEarliestDate() { const dates = Array.from(this.allNews.keys()); if (dates.length === 0) return null; return dates.sort((a, b) => new Date(a) - new Date(b))[0]; } /* showLoading(show) { this.isLoading = show; if (show) { this.loadingIndicator.classList.remove('hidden'); } else { this.loadingIndicator.classList.add('hidden'); } } */ showLoading(show) { this.isLoading = show; if (show) { this.loadingIndicator.classList.remove('hidden'); // 确保加载指示器可见 this.loadingIndicator.style.display = 'flex'; } else { this.loadingIndicator.classList.add('hidden'); this.loadingIndicator.style.display = 'none'; } } showError(message) { const errorDiv = document.createElement('div'); errorDiv.className = 'bg-red-50 border border-red-200 rounded-lg p-4 mb-4'; errorDiv.innerHTML = `
${message}
`; this.newsContainer.insertBefore(errorDiv, this.newsContainer.firstChild); // 3秒后自动移除错误提示 setTimeout(() => { if (errorDiv.parentNode) { errorDiv.parentNode.removeChild(errorDiv); } }, 3000); } delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } } // 全局函数:切换新闻内容显示/隐藏 window.toggleNewsContent = function(newsId) { const contentElement = document.getElementById(`content-${newsId}`); const arrowElement = document.getElementById(`arrow-${newsId}`); if (contentElement && arrowElement) { const isExpanded = contentElement.classList.contains('expanded'); if (isExpanded) { contentElement.classList.remove('expanded'); arrowElement.style.transform = 'rotate(0deg)'; } else { contentElement.classList.add('expanded'); arrowElement.style.transform = 'rotate(180deg)'; } } }; // 初始化应用 document.addEventListener('DOMContentLoaded', () => { new NewsApp(); });