From 00e2f6ac88d8283dd4b03c7314c893d60145d253 Mon Sep 17 00:00:00 2001 From: Kawaxxxsaki <1111@123.com> Date: Sun, 21 Dec 2025 22:53:26 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(database):=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=88=B3=E6=A0=BC=E5=BC=8F=E4=B8=BAISO?= =?UTF-8?q?=E6=A0=87=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将数据库备份文件中的时间戳从本地化格式改为ISO 8601标准格式,提高数据一致性和可读性 --- database/backup_2025-12-21T14-30-37-825Z.sql | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/database/backup_2025-12-21T14-30-37-825Z.sql b/database/backup_2025-12-21T14-30-37-825Z.sql index 4dd7142..903f9b8 100644 --- a/database/backup_2025-12-21T14-30-37-825Z.sql +++ b/database/backup_2025-12-21T14-30-37-825Z.sql @@ -17,10 +17,10 @@ CREATE TABLE `classes` ( -- Dumping data for table `classes` INSERT INTO `classes` VALUES -(1, '计算机2301', '2023', '计算机科学与技术', 2001, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(2, '软件工程2302', '2023', '软件工程', 2002, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'); - +(1, '计算机2301', '2023', '计算机科学与技术', 2001, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(2, '软件工程2302', '2023', '软件工程', 2002, '2025-12-21 14:23:14', '2025-12-21 14:23:14'); +0 -- Table structure for table `courses` DROP TABLE IF EXISTS `courses`; CREATE TABLE `courses` ( @@ -43,9 +43,9 @@ CREATE TABLE `courses` ( -- Dumping data for table `courses` INSERT INTO `courses` VALUES -(1, 'CS101', '高级程序设计', '4.0', 2001, 1, NULL, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(2, 'SE201', '软件工程导论', '3.0', 2002, 2, NULL, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(3, 'MAT101', '高等数学', '5.0', 2003, 1, NULL, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'); +(1, 'CS101', '高级程序设计', '4.0', 2001, 1, NULL, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(2, 'SE201', '软件工程导论', '3.0', 2002, 2, NULL, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(3, 'MAT101', '高等数学', '5.0', 2003, 1, NULL, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'); -- Table structure for table `grades` @@ -74,10 +74,10 @@ CREATE TABLE `grades` ( -- Dumping data for table `grades` INSERT INTO `grades` VALUES -(1, 3001, 1, '90.00', '85.00', '88.00', '87.70', '3.00', NULL, 2001, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(2, 3001, 3, '80.00', '75.00', '82.00', '79.30', '2.00', NULL, 2003, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(3, 3002, 1, '95.00', '92.00', '94.00', '93.70', '4.00', NULL, 2001, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'), -(4, 3003, 2, '88.00', '80.00', '85.00', '84.40', '3.00', NULL, 2002, NULL, 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)', 'Sun Dec 21 2025 14:23:14 GMT+0800 (中国标准时间)'); +(1, 3001, 1, '90.00', '85.00', '88.00', '87.70', '3.00', NULL, 2001, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(2, 3001, 3, '80.00', '75.00', '82.00', '79.30', '2.00', NULL, 2003, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(3, 3002, 1, '95.00', '92.00', '94.00', '93.70', '4.00', NULL, 2001, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'), +(4, 3003, 2, '88.00', '80.00', '85.00', '84.40', '3.00', NULL, 2002, NULL, '2025-12-21 14:23:14', '2025-12-21 14:23:14'); -- Table structure for table `operation_logs` From f360194efdad484d2fb74c85788bb63a4e47cd78 Mon Sep 17 00:00:00 2001 From: Kawaxxxsaki <1111@123.com> Date: Sun, 21 Dec 2025 22:55:43 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(=E5=AD=A6=E7=94=9F):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=AD=A6=E7=94=9F=E8=AF=BE=E7=A8=8B=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 后端添加获取学生课程列表的API路由 - 实现Course模型中的findByStudentId方法查询学生课程 - 新增学生控制器的getCourses方法处理课程请求 - 前端添加课程表格展示及刷新功能 --- backend/controllers/studentController.js | 14 ++++++ backend/models/Course.js | 13 ++++++ backend/routes/student.js | 1 + backend/services/studentService.js | 15 ++++-- frontend/public/js/student.js | 59 +++++++++++++++++++++++- frontend/views/student/dashboard.html | 33 +++++++++++++ 6 files changed, 129 insertions(+), 6 deletions(-) diff --git a/backend/controllers/studentController.js b/backend/controllers/studentController.js index ed1975a..8f72a60 100644 --- a/backend/controllers/studentController.js +++ b/backend/controllers/studentController.js @@ -30,6 +30,20 @@ class StudentController { error(res, '服务器错误'); } } + + static async getCourses(req, res) { + try { + const userId = req.session.user.id; + const data = await StudentService.getStudentCourses(userId); + success(res, data); + } catch (err) { + if (err.message === '学生信息不存在') { + return error(res, err.message, 404); + } + console.error('Get Courses Error:', err); + error(res, '服务器错误'); + } + } } module.exports = StudentController; \ No newline at end of file diff --git a/backend/models/Course.js b/backend/models/Course.js index bff2e83..3d4b9af 100644 --- a/backend/models/Course.js +++ b/backend/models/Course.js @@ -12,6 +12,19 @@ class Course { const rows = await db.query('SELECT * FROM courses WHERE id = ?', [id]); return rows[0]; } + + static async findByStudentId(studentId) { + const sql = ` + SELECT c.*, u.name as teacher_name + FROM courses c + JOIN classes cl ON c.class_id = cl.id + JOIN students s ON cl.class_name = s.class + JOIN users u ON c.teacher_id = u.id + WHERE s.id = ? + ORDER BY c.course_code + `; + return await db.query(sql, [studentId]); + } } module.exports = Course; \ No newline at end of file diff --git a/backend/routes/student.js b/backend/routes/student.js index 478fa0e..4b559b8 100644 --- a/backend/routes/student.js +++ b/backend/routes/student.js @@ -5,5 +5,6 @@ const { requireAuth, requireRole } = require('../middleware/auth'); router.get('/grades', requireAuth, requireRole(['student']), StudentController.getGrades); router.get('/grades/:id', requireAuth, requireRole(['student']), StudentController.getGradeDetails); +router.get('/courses', requireAuth, requireRole(['student']), StudentController.getCourses); module.exports = router; \ No newline at end of file diff --git a/backend/services/studentService.js b/backend/services/studentService.js index 1e8796b..c0af4eb 100644 --- a/backend/services/studentService.js +++ b/backend/services/studentService.js @@ -1,12 +1,9 @@ const Score = require('../models/Score'); const Student = require('../models/Student'); +const Course = require('../models/Course'); class StudentService { static async getStudentGrades(userId) { - // 先通过 userId 获取 studentId - // 假设 users.id = students.id,或者通过 user_id 关联 - // 根据之前的 authService,我们假设 users.id 就是 students.id - // 确认学生是否存在 const student = await Student.findById(userId); if (!student) { @@ -50,6 +47,14 @@ class StudentService { } return grade; } + + static async getStudentCourses(userId) { + const student = await Student.findById(userId); + if (!student) { + throw new Error('学生信息不存在'); + } + return await Course.findByStudentId(userId); + } } -module.exports = StudentService; \ No newline at end of file +module.exports = StudentService; diff --git a/frontend/public/js/student.js b/frontend/public/js/student.js index cfd19d8..4b9bb04 100644 --- a/frontend/public/js/student.js +++ b/frontend/public/js/student.js @@ -9,8 +9,15 @@ class StudentManager { init() { this.initDashboard(); + this.initCourses(); this.updateCurrentTime(); setInterval(() => this.updateCurrentTime(), 1000); + + // 绑定刷新按钮 + const refreshBtn = document.getElementById('refreshCourses'); + if (refreshBtn) { + refreshBtn.addEventListener('click', () => this.initCourses()); + } } updateCurrentTime() { @@ -44,6 +51,51 @@ class StudentManager { console.error('Fetch dashboard data failed:', error); } } + + async initCourses() { + // 检查是否在仪表板页面 + if (!document.getElementById('coursesTableBody')) return; + + try { + const response = await fetch(`${this.apiBase}/courses`); + const result = await response.json(); + + if (result.success) { + this.renderCourses(result.data); + } else { + if (window.authManager) { + window.authManager.showNotification(result.message || '获取课程失败', 'error'); + } + } + } catch (error) { + console.error('Fetch courses failed:', error); + } + } + + renderCourses(courses) { + const tbody = document.getElementById('coursesTableBody'); + if (tbody) { + if (!courses || courses.length === 0) { + tbody.innerHTML = '暂无课程安排'; + return; + } + + tbody.innerHTML = courses.map(course => ` + + ${course.course_code} + ${course.course_name} + ${course.credit} + ${course.teacher_name} + ${course.semester || '2023-2024 下学期'} + + + + + `).join(''); + } + } renderDashboard(data) { const { grades, statistics } = data; @@ -88,6 +140,11 @@ class StudentManager { } } + viewCourseDetails(id) { + console.log('View details for course:', id); + // 可以弹出一个模态框显示更多信息 + } + updateElement(id, value) { const el = document.getElementById(id); if (el) el.textContent = value; @@ -132,4 +189,4 @@ document.addEventListener('DOMContentLoaded', () => { if (studentClassEl) studentClassEl.textContent = user.class || '未分配'; } }); -}); \ No newline at end of file +}); diff --git a/frontend/views/student/dashboard.html b/frontend/views/student/dashboard.html index d10be6e..1fb9a84 100644 --- a/frontend/views/student/dashboard.html +++ b/frontend/views/student/dashboard.html @@ -337,6 +337,39 @@ + +
+
+
我的课程
+ +
+
+ + + + + + + + + + + + + + + + + +
课程代码课程名称学分授课教师学期操作
+
+ 数据加载中... +
+
+
+