207 lines
6.0 KiB
JavaScript
Raw Permalink Normal View History

/**
* bulletin.js - M22公告栏主逻辑
* 修复URL编码问题 · 频道筛选正常
*/
document.addEventListener('DOMContentLoaded', async () => {
// 显示骨架屏
showSkeleton();
// 初始化频道
initializeChannels();
// 加载公告数据
await loadAnnouncements();
// 监听路由变化
window.addEventListener('hashchange', handleRouteChange);
});
// 当前频道
let currentChannel = '全部';
// 所有公告数据
let allAnnouncements = [];
// 初始化频道
function initializeChannels() {
const channelTabs = document.querySelectorAll('.channel-tab');
// 从URL Hash恢复当前频道需要解码
const rawHash = window.location.hash.slice(1) || '全部';
currentChannel = decodeURIComponent(rawHash);
// 设置激活状态并绑定事件
channelTabs.forEach(tab => {
const channel = tab.dataset.channel;
if (channel === currentChannel) {
tab.classList.add('active');
} else {
tab.classList.remove('active');
}
// 绑定点击事件
tab.onclick = function(e) {
e.preventDefault();
const clickChannel = this.dataset.channel;
console.log('点击频道:', clickChannel);
// 直接设置中文hash浏览器会自动编码
window.location.hash = clickChannel;
};
});
}
// 显示骨架屏
function showSkeleton() {
const skeletonContainer = document.getElementById('skeleton-container');
if (skeletonContainer) {
skeletonContainer.style.display = 'block';
}
const bulletinContainer = document.querySelector('.bulletin-container');
if (bulletinContainer) {
bulletinContainer.innerHTML = '';
}
}
// 隐藏骨架屏
function hideSkeleton() {
const skeletonContainer = document.getElementById('skeleton-container');
if (skeletonContainer) {
skeletonContainer.style.display = 'none';
}
}
// 渲染公告(带筛选功能)
function renderAnnouncements(announcements) {
// 隐藏骨架屏
hideSkeleton();
const container = document.querySelector('.bulletin-container');
if (!container) return;
console.log('当前频道:', currentChannel, '总公告数:', announcements.length);
// 根据当前频道筛选
let filtered = [];
if (currentChannel === '全部') {
filtered = announcements;
} else {
filtered = announcements.filter(a => a.channel === currentChannel);
}
console.log('筛选后条数:', filtered.length);
// 如果没有公告,显示空状态
if (filtered.length === 0) {
container.innerHTML = `
<div class="empty-state">
<div class="empty-icon">📭</div>
<div class="empty-title">这里还没有公告</div>
<div class="empty-desc">当前频道${currentChannel}没有公告</div>
</div>
`;
return;
}
// 生成公告HTML
let html = '';
for (let i = 0; i < filtered.length; i++) {
const a = filtered[i];
html += `
<article class="bulletin-item">
<h2 class="bulletin-title">${a.title}</h2>
<div class="bulletin-meta">
<span class="bulletin-channel">#${a.channel}</span>
<time class="bulletin-date">${a.date}</time>
</div>
<div class="bulletin-content">${a.content}</div>
</article>
`;
}
container.innerHTML = html;
// 更新底部计数
const totalSpan = document.getElementById('totalCount');
if (totalSpan) {
totalSpan.textContent = announcements.length;
}
}
// 路由变化处理
function handleRouteChange() {
// 获取hash并解码比如 %E5%9B%A2%E9%98%9F%E6%B6%88%E6%81%AF -> 团队消息)
const rawHash = window.location.hash.slice(1) || '全部';
const newChannel = decodeURIComponent(rawHash);
console.log('路由变化 - 原始hash:', rawHash, '解码后:', newChannel, '当前频道:', currentChannel);
if (newChannel !== currentChannel) {
currentChannel = newChannel;
// 更新频道激活状态
document.querySelectorAll('.channel-tab').forEach(tab => {
const channel = tab.dataset.channel;
if (channel === newChannel) {
tab.classList.add('active');
} else {
tab.classList.remove('active');
}
});
// 重新渲染
if (allAnnouncements && allAnnouncements.length > 0) {
console.log('重新渲染,当前频道:', currentChannel);
renderAnnouncements(allAnnouncements);
}
}
}
// 加载公告
async function loadAnnouncements() {
try {
const result = await bulletinAPI.getAnnouncements();
if (result.success) {
allAnnouncements = result.data;
renderAnnouncements(result.data);
console.log(`[公告加载] 成功 | 条数: ${result.data.length}`);
} else {
showError(result.error);
}
} catch (error) {
console.error('加载公告失败:', error);
showError({
title: '🧸 出错了',
message: '加载公告时遇到问题',
retryable: true
});
}
}
// 显示错误
function showError(errorInfo) {
hideSkeleton();
const container = document.querySelector('.bulletin-container');
if (!container) return;
const retryButton = errorInfo.retryable ?
`<button class="retry-btn" onclick="window.loadAnnouncements()">重试</button>` : '';
container.innerHTML = `
<div class="error-state">
<div class="error-icon">🧸</div>
<div class="error-title">${errorInfo.title || '哎呀'}</div>
<div class="error-message">${errorInfo.message || '服务暂时不可用'}</div>
${retryButton}
</div>
`;
}
// 暴露给全局
window.loadAnnouncements = loadAnnouncements;