// main.js - 主脚本文件 // 页面导航功能 function setupNavigation() { // 侧边栏菜单项 const menuItems = document.querySelectorAll('nav a'); const contentSections = [ document.getElementById('dashboard-content'), document.getElementById('shield-content'), document.getElementById('hosts-content'), document.getElementById('query-content'), document.getElementById('logs-content'), document.getElementById('config-content') ]; const pageTitle = document.getElementById('page-title'); menuItems.forEach((item, index) => { item.addEventListener('click', (e) => { // 允许浏览器自动更新地址栏中的hash,不阻止默认行为 // 移动端点击菜单项后自动关闭侧边栏 if (window.innerWidth < 768) { closeSidebar(); } }); }); // 移动端侧边栏切换 const toggleSidebar = document.getElementById('toggle-sidebar'); const closeSidebarBtn = document.getElementById('close-sidebar'); const sidebar = document.getElementById('sidebar'); const sidebarOverlay = document.getElementById('sidebar-overlay'); // 打开侧边栏函数 function openSidebar() { console.log('Opening sidebar...'); if (sidebar) { sidebar.classList.remove('-translate-x-full'); sidebar.classList.add('translate-x-0'); } if (sidebarOverlay) { sidebarOverlay.classList.remove('hidden'); sidebarOverlay.classList.add('block'); } // 防止页面滚动 document.body.style.overflow = 'hidden'; console.log('Sidebar opened successfully'); } // 关闭侧边栏函数 function closeSidebar() { console.log('Closing sidebar...'); if (sidebar) { sidebar.classList.add('-translate-x-full'); sidebar.classList.remove('translate-x-0'); } if (sidebarOverlay) { sidebarOverlay.classList.add('hidden'); sidebarOverlay.classList.remove('block'); } // 恢复页面滚动 document.body.style.overflow = ''; console.log('Sidebar closed successfully'); } // 切换侧边栏函数 function toggleSidebarVisibility() { console.log('Toggling sidebar visibility...'); console.log('Current sidebar classes:', sidebar ? sidebar.className : 'sidebar not found'); if (sidebar && sidebar.classList.contains('-translate-x-full')) { console.log('Sidebar is hidden, opening...'); openSidebar(); } else { console.log('Sidebar is visible, closing...'); closeSidebar(); } } // 绑定切换按钮事件 if (toggleSidebar) { toggleSidebar.addEventListener('click', toggleSidebarVisibility); } // 绑定关闭按钮事件 if (closeSidebarBtn) { closeSidebarBtn.addEventListener('click', closeSidebar); } // 绑定遮罩层点击事件 if (sidebarOverlay) { sidebarOverlay.addEventListener('click', closeSidebar); } // 移动端点击菜单项后自动关闭侧边栏 menuItems.forEach(item => { item.addEventListener('click', () => { // 检查是否是移动设备视图 if (window.innerWidth < 768) { closeSidebar(); } }); }); // 添加键盘事件监听,按ESC键关闭侧边栏 document.addEventListener('keydown', (e) => { if (e.key === 'Escape') { closeSidebar(); } }); } // 页面初始化函数 - 根据当前hash值初始化对应页面 function initPageByHash() { const hash = window.location.hash.substring(1); // 隐藏所有内容区域 const contentSections = [ document.getElementById('dashboard-content'), document.getElementById('shield-content'), document.getElementById('hosts-content'), document.getElementById('query-content'), document.getElementById('logs-content'), document.getElementById('config-content') ]; contentSections.forEach(section => { if (section) { section.classList.add('hidden'); } }); // 显示当前页面内容 const currentSection = document.getElementById(`${hash}-content`); if (currentSection) { currentSection.classList.remove('hidden'); } // 更新页面标题 const pageTitle = document.getElementById('page-title'); if (pageTitle) { const titles = { 'dashboard': '仪表盘', 'shield': '屏蔽管理', 'hosts': 'Hosts管理', 'query': 'DNS屏蔽查询', 'logs': '查询日志', 'config': '系统设置' }; pageTitle.textContent = titles[hash] || '仪表盘'; } // 页面特定初始化 - 使用setTimeout延迟调用,确保所有脚本文件都已加载完成 if (hash === 'shield') { setTimeout(() => { if (typeof initShieldPage === 'function') { initShieldPage(); } }, 0); } else if (hash === 'hosts') { setTimeout(() => { if (typeof initHostsPage === 'function') { initHostsPage(); } }, 0); } else if (hash === 'logs') { setTimeout(() => { if (typeof initLogsPage === 'function') { initLogsPage(); } }, 0); } else if (hash === 'dashboard') { setTimeout(() => { if (typeof loadDashboardData === 'function') { loadDashboardData(); } }, 0); } } // 初始化函数 function init() { // 设置导航 setupNavigation(); // 初始化页面 initPageByHash(); // 添加hashchange事件监听,处理浏览器前进/后退按钮 window.addEventListener('hashchange', initPageByHash); // 定期更新系统状态 setInterval(updateSystemStatus, 5000); } // 更新系统状态 function updateSystemStatus() { fetch('/api/status') .then(response => response.json()) .then(data => { const uptimeElement = document.getElementById('uptime'); if (uptimeElement) { uptimeElement.textContent = `正常运行中 | ${formatUptime(data.uptime)}`; } }) .catch(error => { console.error('更新系统状态失败:', error); const uptimeElement = document.getElementById('uptime'); if (uptimeElement) { uptimeElement.textContent = '连接异常'; uptimeElement.classList.add('text-danger'); } }); } // 格式化运行时间 function formatUptime(milliseconds) { // 简化版的格式化,实际使用时需要根据API返回的数据格式调整 const seconds = Math.floor(milliseconds / 1000); const minutes = Math.floor(seconds / 60); const hours = Math.floor(minutes / 60); const days = Math.floor(hours / 24); if (days > 0) { return `${days}天${hours % 24}小时`; } else if (hours > 0) { return `${hours}小时${minutes % 60}分钟`; } else if (minutes > 0) { return `${minutes}分钟${seconds % 60}秒`; } else { return `${seconds}秒`; } } // 账户功能 - 下拉菜单、注销和修改密码 function setupAccountFeatures() { // 下拉菜单功能 const accountDropdown = document.getElementById('account-dropdown'); const accountMenu = document.getElementById('account-menu'); const changePasswordBtn = document.getElementById('change-password-btn'); const logoutBtn = document.getElementById('logout-btn'); const changePasswordModal = document.getElementById('change-password-modal'); const closeModalBtn = document.getElementById('close-modal-btn'); const cancelChangePasswordBtn = document.getElementById('cancel-change-password'); const changePasswordForm = document.getElementById('change-password-form'); const passwordMismatch = document.getElementById('password-mismatch'); const newPassword = document.getElementById('new-password'); const confirmPassword = document.getElementById('confirm-password'); // 点击外部关闭下拉菜单 document.addEventListener('click', (e) => { if (accountDropdown && !accountDropdown.contains(e.target)) { accountMenu.classList.add('hidden'); } }); // 点击账户区域切换下拉菜单 if (accountDropdown) { accountDropdown.addEventListener('click', (e) => { e.stopPropagation(); accountMenu.classList.toggle('hidden'); }); } // 打开修改密码模态框 if (changePasswordBtn) { changePasswordBtn.addEventListener('click', () => { accountMenu.classList.add('hidden'); changePasswordModal.classList.remove('hidden'); document.body.style.overflow = 'hidden'; }); } // 关闭修改密码模态框 function closeModal() { changePasswordModal.classList.add('hidden'); document.body.style.overflow = ''; changePasswordForm.reset(); passwordMismatch.classList.add('hidden'); } // 绑定关闭模态框事件 if (closeModalBtn) { closeModalBtn.addEventListener('click', closeModal); } if (cancelChangePasswordBtn) { cancelChangePasswordBtn.addEventListener('click', closeModal); } // 点击模态框外部关闭模态框 if (changePasswordModal) { changePasswordModal.addEventListener('click', (e) => { if (e.target === changePasswordModal) { closeModal(); } }); } // 按ESC键关闭模态框 document.addEventListener('keydown', (e) => { if (e.key === 'Escape' && !changePasswordModal.classList.contains('hidden')) { closeModal(); } }); // 密码匹配验证 if (newPassword && confirmPassword) { confirmPassword.addEventListener('input', () => { if (newPassword.value !== confirmPassword.value) { passwordMismatch.classList.remove('hidden'); } else { passwordMismatch.classList.add('hidden'); } }); newPassword.addEventListener('input', () => { if (newPassword.value !== confirmPassword.value) { passwordMismatch.classList.remove('hidden'); } else { passwordMismatch.classList.add('hidden'); } }); } // 修改密码表单提交 if (changePasswordForm) { changePasswordForm.addEventListener('submit', async (e) => { e.preventDefault(); // 验证密码匹配 if (newPassword.value !== confirmPassword.value) { passwordMismatch.classList.remove('hidden'); return; } const formData = new FormData(changePasswordForm); const data = { currentPassword: formData.get('currentPassword'), newPassword: formData.get('newPassword') }; try { const response = await fetch('/api/change-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const result = await response.json(); if (response.ok && result.status === 'success') { // 密码修改成功 alert('密码修改成功'); closeModal(); } else { // 密码修改失败 alert(result.error || '密码修改失败'); } } catch (error) { console.error('修改密码失败:', error); alert('修改密码失败,请稍后重试'); } }); } // 注销功能 if (logoutBtn) { logoutBtn.addEventListener('click', async () => { try { await fetch('/api/logout', { method: 'POST' }); // 重定向到登录页面 window.location.href = '/login'; } catch (error) { console.error('注销失败:', error); alert('注销失败,请稍后重试'); } }); } } // 初始化函数 function init() { // 设置导航 setupNavigation(); // 设置账户功能 setupAccountFeatures(); // 初始化页面 initPageByHash(); // 添加hashchange事件监听,处理浏览器前进/后退按钮 window.addEventListener('hashchange', initPageByHash); // 定期更新系统状态 setInterval(updateSystemStatus, 5000); } // 页面加载完成后执行初始化 window.addEventListener('DOMContentLoaded', init);