(() => { let notificationInterval = null; let isOpen = false; let isInitialized = false; // 格式化时间 function formatTime(ts) { if (!ts) return ''; try { // 解析ISO格式的时间字符串(已经是北京时间) const date = new Date(ts); const now = new Date(); // 计算时间差(毫秒) const diff = now - date; const minutes = Math.floor(diff / 60000); const hours = Math.floor(diff / 3600000); const days = Math.floor(diff / 86400000); if (minutes < 1) return '刚刚'; if (minutes < 60) return `${minutes}分钟前`; if (hours < 24) return `${hours}小时前`; if (days < 7) return `${days}天前`; // 超过7天显示完整日期 return date.toLocaleString('zh-CN', { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' }); } catch (e) { console.error('时间格式化错误:', e, ts); return ts; } } // 获取操作的中文描述 function getActionText(action) { const actionMap = { '批量上传MAC文件': '批量上传了MAC文件', '批量上传发货记录文件': '批量上传了发货记录', '添加人员信息': '添加了人员信息', '上传发货记录': '上传了发货记录', '上传MAC与批次': '上传了MAC与批次', '批量上传不良明细文件': '批量上传了不良明细', '上传返修记录': '上传了返修记录', '上传良/不良统计': '上传了良/不良统计', '上传不良明细': '上传了不良明细' }; return actionMap[action] || action; } // 更新未读数量 async function updateUnreadCount() { try { const data = await API.getUnreadCount(); const badge = document.getElementById('notification-badge'); const count = data.count || 0; const previousCount = parseInt(badge.textContent) || 0; if (count > 0) { badge.textContent = count > 99 ? '99+' : count; badge.style.display = 'block'; // 如果有新消息且面板是打开的,自动刷新列表 if (count > previousCount && isOpen) { console.log('[Notifications] 检测到新消息,刷新列表'); await loadNotifications(); } } else { badge.style.display = 'none'; } } catch (e) { console.error('获取未读数量失败:', e); } } // 加载通知列表 async function loadNotifications() { try { const data = await API.getNotifications(); const list = data.list || []; const container = document.getElementById('notification-list'); if (list.length === 0) { container.innerHTML = '
暂无消息通知
'; return; } container.innerHTML = list.map(item => `
${item.username || '用户'}
${getActionText(item.action)}
${item.detail ? `
${item.detail}
` : ''}
${formatTime(item.ts)}
`).join(''); // 为每个通知项添加点击事件 container.querySelectorAll('.notification-item').forEach(item => { item.addEventListener('click', async () => { const id = item.dataset.id; if (item.classList.contains('unread')) { try { await API.markNotificationRead(id); item.classList.remove('unread'); await updateUnreadCount(); } catch (e) { console.error('标记已读失败:', e); } } }); }); } catch (e) { console.error('加载通知失败:', e); } } // 切换通知面板 function togglePanel() { const panel = document.getElementById('notification-panel'); if (!panel) { console.error('[Notifications] 找不到面板元素'); return; } isOpen = !isOpen; console.log('[Notifications] 面板状态:', isOpen ? '打开' : '关闭'); if (isOpen) { panel.style.display = 'flex'; loadNotifications(); } else { panel.style.display = 'none'; } } // 初始化通知系统 async function initNotifications() { // 防止重复初始化 if (isInitialized) { console.log('[Notifications] 已经初始化,跳过'); return; } try { // 检查用户角色 const user = await API.me(); if (user.role !== 'superadmin') { console.log('[Notifications] 非超级管理员,不显示通知'); return; // 只有超级管理员才显示通知铃铛 } // 显示通知铃铛 const bell = document.getElementById('notification-bell'); if (!bell) { console.error('[Notifications] 找不到铃铛元素'); return; } bell.style.display = 'inline-flex'; console.log('[Notifications] 铃铛已显示'); // 移除旧的事件监听器(如果有) const newBell = bell.cloneNode(true); bell.parentNode.replaceChild(newBell, bell); // 绑定铃铛点击事件 newBell.addEventListener('click', (e) => { console.log('[Notifications] 铃铛被点击'); e.preventDefault(); e.stopPropagation(); togglePanel(); }); // 绑定全部标记为已读按钮(移除旧的事件监听器) const markAllBtn = document.getElementById('mark-all-read'); if (markAllBtn) { const newMarkAllBtn = markAllBtn.cloneNode(true); markAllBtn.parentNode.replaceChild(newMarkAllBtn, markAllBtn); newMarkAllBtn.addEventListener('click', async (e) => { e.stopPropagation(); try { await API.markAllNotificationsRead(); await loadNotifications(); await updateUnreadCount(); API.toast('已全部标记为已读'); } catch (e) { console.error('标记全部已读失败:', e); } }); } // 绑定删除已读消息按钮(移除旧的事件监听器) const deleteBtn = document.getElementById('delete-read'); if (deleteBtn) { const newDeleteBtn = deleteBtn.cloneNode(true); deleteBtn.parentNode.replaceChild(newDeleteBtn, deleteBtn); newDeleteBtn.addEventListener('click', async (e) => { e.stopPropagation(); if (!confirm('确定要删除所有已读消息吗?')) { return; } try { const result = await API.deleteReadNotifications(); await loadNotifications(); await updateUnreadCount(); API.toast(`已删除 ${result.count || 0} 条已读消息`); } catch (e) { console.error('删除已读消息失败:', e); } }); } // 点击其他地方关闭面板 document.addEventListener('click', (e) => { const panel = document.getElementById('notification-panel'); const currentBell = document.getElementById('notification-bell'); if (isOpen && panel && currentBell && !panel.contains(e.target) && !currentBell.contains(e.target)) { isOpen = false; panel.style.display = 'none'; } }); // 初始加载未读数量 await updateUnreadCount(); // 每5秒更新一次未读数量(实时检查新消息) if (notificationInterval) { clearInterval(notificationInterval); } notificationInterval = setInterval(updateUnreadCount, 5000); isInitialized = true; console.log('[Notifications] 初始化完成,实时轮询已启动(5秒间隔)'); } catch (e) { console.error('初始化通知系统失败:', e); } } // 清理定时器 function cleanupNotifications() { if (notificationInterval) { clearInterval(notificationInterval); notificationInterval = null; } isInitialized = false; isOpen = false; console.log('[Notifications] 已清理'); } // 导出到全局 window.NotificationSystem = { init: initNotifications, cleanup: cleanupNotifications, refresh: updateUnreadCount }; })();