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();
});