class AuthManager { constructor() { // 动态设置API基础URL,支持file:///协议和localhost:3000访问 this.apiBase = window.location.protocol === 'file:' ? 'http://localhost:3000/api' : '/api'; this.initEventListeners(); this.checkAuthStatus(); } async checkAuthStatus() { try { const response = await fetch(`${this.apiBase}/auth/me`); const data = await response.json(); if (data.success && data.user) { // 用户已登录,根据角色重定向到正确的仪表板 const userRole = data.user.role; let redirectUrl = '/dashboard'; if (userRole === 'student') { redirectUrl = '/frontend/html/student_dashboard.html'; } else if (userRole === 'teacher') { redirectUrl = '/frontend/html/teacher_dashboard.html'; } else if (userRole === 'admin') { redirectUrl = '/frontend/html/admin_dashboard.html'; } // 如果当前页面是登录或注册页面,则重定向到仪表板 const currentPath = window.location.pathname; if (currentPath.includes('login.html') || currentPath.includes('register.html')) { window.location.href = redirectUrl; } // 如果当前页面不是正确的仪表板页面,则重定向 else if (!currentPath.includes(redirectUrl) && currentPath !== '/' && !currentPath.includes('index.html')) { window.location.href = redirectUrl; } } } catch (error) { console.log('用户未登录'); } } initEventListeners() { // 登录表单提交 const loginForm = document.getElementById('loginForm'); if (loginForm) { loginForm.addEventListener('submit', (e) => this.handleLogin(e)); } // 注册表单提交 const registerForm = document.getElementById('registerForm'); if (registerForm) { registerForm.addEventListener('submit', (e) => this.handleRegister(e)); } // 登出按钮 const logoutBtn = document.getElementById('logoutBtn'); if (logoutBtn) { logoutBtn.addEventListener('click', (e) => this.handleLogout(e)); } } async handleLogin(e) { e.preventDefault(); const form = e.target; const formData = new FormData(form); const data = Object.fromEntries(formData.entries()); const submitBtn = form.querySelector('button[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.innerHTML = ' 登录中...'; submitBtn.disabled = true; try { const response = await fetch(`${this.apiBase}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const result = await response.json(); if (result.success) { this.showNotification('登录成功!正在跳转...', 'success'); // 根据用户角色跳转到不同的仪表板 const userRole = result.user?.role; let redirectUrl = '/dashboard'; if (userRole === 'student') { redirectUrl = '/frontend/html/student_dashboard.html'; } else if (userRole === 'teacher') { redirectUrl = '/frontend/html/teacher_dashboard.html'; } else if (userRole === 'admin') { redirectUrl = '/frontend/html/admin_dashboard.html'; } // 延迟跳转以显示通知 setTimeout(() => { window.location.href = redirectUrl; }, 1500); } else { this.showNotification(result.message || '登录失败', 'error'); submitBtn.innerHTML = originalText; submitBtn.disabled = false; } } catch (error) { console.error('登录错误:', error); this.showNotification('网络错误,请重试', 'error'); submitBtn.innerHTML = originalText; submitBtn.disabled = false; } } async handleRegister(e) { e.preventDefault(); const form = e.target; const formData = new FormData(form); const data = Object.fromEntries(formData.entries()); // 验证密码 if (data.password !== data.confirmPassword) { this.showNotification('两次输入的密码不一致', 'error'); return; } const submitBtn = form.querySelector('button[type="submit"]'); const originalText = submitBtn.innerHTML; submitBtn.innerHTML = ' 注册中...'; submitBtn.disabled = true; try { const response = await fetch(`${this.apiBase}/auth/register`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); const result = await response.json(); if (result.success) { this.showNotification('注册成功!正在跳转到登录页面...', 'success'); setTimeout(() => { window.location.href = '/html/login.html'; }, 1500); } else { this.showNotification(result.message || '注册失败', 'error'); submitBtn.innerHTML = originalText; submitBtn.disabled = false; } } catch (error) { console.error('注册错误:', error); this.showNotification('网络错误,请重试', 'error'); submitBtn.innerHTML = originalText; submitBtn.disabled = false; } } async handleLogout(e) { e.preventDefault(); if (!confirm('确定要退出登录吗?')) { return; } try { const response = await fetch(`${this.apiBase}/auth/logout`, { method: 'POST' }); const result = await response.json(); if (result.success) { this.showNotification('已成功退出登录', 'success'); setTimeout(() => { window.location.href = '/'; }, 1000); } else { this.showNotification('退出登录失败', 'error'); } } catch (error) { console.error('退出登录错误:', error); this.showNotification('网络错误,请重试', 'error'); } } showNotification(message, type = 'info') { // 移除现有的通知 const existingNotification = document.querySelector('.notification'); if (existingNotification) { existingNotification.remove(); } // 创建新的通知 const notification = document.createElement('div'); notification.className = `notification notification-${type}`; notification.innerHTML = ` ${message} `; // 样式 notification.style.cssText = ` position: fixed; top: 20px; right: 20px; background: ${type === 'success' ? '#10b981' : type === 'error' ? '#ef4444' : '#3b82f6'}; color: white; padding: 15px 20px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); display: flex; align-items: center; gap: 10px; z-index: 1000; animation: slideIn 0.3s ease; `; document.body.appendChild(notification); // 3秒后自动移除 setTimeout(() => { notification.style.animation = 'slideOut 0.3s ease'; setTimeout(() => notification.remove(), 300); }, 3000); // 添加动画关键帧 if (!document.querySelector('#notification-styles')) { const style = document.createElement('style'); style.id = 'notification-styles'; style.textContent = ` @keyframes slideIn { from { transform: translateX(100%); opacity: 0; } to { transform: translateX(0); opacity: 1; } } @keyframes slideOut { from { transform: translateX(0); opacity: 1; } to { transform: translateX(100%); opacity: 0; } } `; document.head.appendChild(style); } } } // 初始化认证管理器 document.addEventListener('DOMContentLoaded', () => { window.authManager = new AuthManager(); });