class StudentManager { constructor() { // 动态设置API基础URL,支持file:///协议和localhost:3000访问 this.apiBase = window.location.protocol === 'file:' ? 'http://localhost:3000/api' : '/api'; this.initDashboard(); this.initGradeDetails(); this.loadProfile(); } async initDashboard() { const gradeList = document.getElementById('gradeList'); const statisticsElement = document.getElementById('statistics'); if (!gradeList) return; try { const response = await fetch(`${this.apiBase}/student/grades`, { credentials: 'include' }); if (response.status === 401) { // 未登录,重定向到登录页 this.showNotification('请先登录', 'error'); setTimeout(() => { window.location.href = '/html/login.html'; }, 1500); return; } const data = await response.json(); if (data.success) { this.renderGrades(data.grades); this.renderStatistics(data.statistics); this.updateChart(data.grades); } else { this.showNotification(data.message || '获取成绩失败', 'error'); } } catch (error) { console.error('获取成绩错误:', error); this.showNotification('网络错误,请重试', 'error'); } } renderGrades(grades) { const gradeList = document.getElementById('gradeList'); const gradeTable = document.getElementById('gradeTable'); if (!gradeTable) return; if (grades.length === 0) { gradeList.innerHTML = `

暂无成绩记录

你还没有任何成绩记录

`; return; } const tbody = gradeTable.querySelector('tbody'); tbody.innerHTML = ''; grades.forEach(grade => { const row = document.createElement('tr'); // 根据分数设置颜色 let scoreClass = ''; if (grade.score >= 90) scoreClass = 'grade-excellent'; else if (grade.score >= 80) scoreClass = 'grade-good'; else if (grade.score >= 60) scoreClass = 'grade-pass'; else scoreClass = 'grade-fail'; row.innerHTML = ` ${grade.course_code} ${grade.course_name} ${grade.credit} ${grade.score} ${grade.grade_level || '-'} ${grade.grade_point || '-'} ${grade.teacher_name} ${new Date(grade.exam_date).toLocaleDateString()} 查看 `; tbody.appendChild(row); }); } renderStatistics(statistics) { const element = document.getElementById('statistics'); if (!element) return; element.innerHTML = `
${statistics.totalCourses}
总课程数
${statistics.totalCredits}
总学分
${statistics.averageScore}
平均分
${statistics.gpa}
平均绩点
`; } async loadProfile() { const profileElement = document.getElementById('profileInfo'); if (!profileElement) return; try { const response = await fetch(`${this.apiBase}/student/profile`, { credentials: 'include' }); if (response.status === 401) { // 未登录,重定向到登录页 this.showNotification('请先登录', 'error'); setTimeout(() => { window.location.href = '/html/login.html'; }, 1500); return; } const data = await response.json(); if (data.success) { const profile = data.profile; // 更新学生仪表板顶部信息 const userNameElement = document.getElementById('userName'); const studentNameElement = document.getElementById('studentName'); const studentClassElement = document.getElementById('studentClass'); if (userNameElement) { userNameElement.textContent = profile.full_name || profile.username; } if (studentNameElement) { studentNameElement.textContent = profile.full_name || profile.username; } if (studentClassElement) { studentClassElement.textContent = profile.class_name || '未设置'; } profileElement.innerHTML = `

${profile.full_name}

学生

学号

${profile.student_id}

班级

${profile.class_name}

专业

${profile.major || '未设置'}

入学年份

${profile.enrollment_year || '未设置'}

`; } else { // API返回失败 this.showNotification(data.message || '获取个人信息失败', 'error'); } } catch (error) { console.error('加载个人信息错误:', error); this.showNotification('网络错误,请重试', 'error'); } } async initGradeDetails() { const urlParams = new URLSearchParams(window.location.search); const gradeId = urlParams.get('id'); if (!gradeId) return; try { const response = await fetch(`${this.apiBase}/student/grades/${gradeId}`, { credentials: 'include' }); const data = await response.json(); if (data.success) { this.renderGradeDetails(data.grade); } else { this.showNotification('获取成绩详情失败', 'error'); setTimeout(() => window.history.back(), 1500); } } catch (error) { console.error('获取成绩详情错误:', error); this.showNotification('网络错误,请重试', 'error'); } } renderGradeDetails(grade) { const container = document.getElementById('gradeDetails'); if (!container) return; // 计算绩点描述 let gradeDescription = ''; if (grade.score >= 90) gradeDescription = '优秀'; else if (grade.score >= 80) gradeDescription = '良好'; else if (grade.score >= 70) gradeDescription = '中等'; else if (grade.score >= 60) gradeDescription = '及格'; else gradeDescription = '不及格'; container.innerHTML = `

${grade.course_name} (${grade.course_code})

${grade.score} 分 ${gradeDescription}

基本信息

学分: ${grade.credit}
学期: ${grade.semester}
考试日期: ${new Date(grade.exam_date).toLocaleDateString()}
等级: ${grade.grade_level || '-'}
绩点: ${grade.grade_point || '-'}

学生信息

姓名: ${grade.full_name}
学号: ${grade.student_number}
班级: ${grade.class_name}
专业: ${grade.major || '未设置'}

教师信息

任课教师: ${grade.teacher_name}
教师邮箱: ${grade.teacher_email}
${grade.remark ? `

备注

${grade.remark}

` : ''}
`; } updateChart(grades) { const ctx = document.getElementById('gradeChart'); if (!ctx) return; if (typeof Chart === 'undefined') { // 如果没有Chart.js,延迟加载 this.loadChartLibrary().then(() => this.updateChart(grades)); return; } const courseNames = grades.map(g => g.course_name); const scores = grades.map(g => g.score); // 销毁现有图表实例 if (window.gradeChart instanceof Chart) { window.gradeChart.destroy(); } window.gradeChart = new Chart(ctx, { type: 'bar', data: { labels: courseNames, datasets: [{ label: '分数', data: scores, backgroundColor: scores.map(score => { if (score >= 90) return 'rgba(75, 192, 192, 0.7)'; if (score >= 80) return 'rgba(54, 162, 235, 0.7)'; if (score >= 60) return 'rgba(255, 206, 86, 0.7)'; return 'rgba(255, 99, 132, 0.7)'; }), borderColor: scores.map(score => { if (score >= 90) return 'rgb(75, 192, 192)'; if (score >= 80) return 'rgb(54, 162, 235)'; if (score >= 60) return 'rgb(255, 206, 86)'; return 'rgb(255, 99, 132)'; }), borderWidth: 1 }] }, options: { responsive: true, plugins: { title: { display: true, text: '各科成绩分布' } }, scales: { y: { beginAtZero: true, max: 100 } } } }); } async loadChartLibrary() { return new Promise((resolve, reject) => { if (typeof Chart !== 'undefined') { resolve(); return; } const script = document.createElement('script'); script.src = 'https://cdn.jsdelivr.net/npm/chart.js'; script.onload = resolve; script.onerror = reject; document.head.appendChild(script); }); } showNotification(message, type = 'info') { // 使用AuthManager的通知系统或自己实现 if (window.authManager && window.authManager.showNotification) { window.authManager.showNotification(message, type); } else { alert(message); } } } // 初始化学生管理器 document.addEventListener('DOMContentLoaded', () => { if (window.location.pathname.includes('/student/')) { window.studentManager = new StudentManager(); } });