const db = require('../config/database'); class Score { static async findByStudentId(studentId) { const sql = ` SELECT s.id, s.student_id, s.course_id, s.teacher_id, s.total_score as score, s.grade_point, s.grade_level, s.created_at, c.course_code, c.course_name, c.credit, u.name as teacher_name FROM grades s JOIN courses c ON s.course_id = c.id JOIN users u ON s.teacher_id = u.id WHERE s.student_id = ? ORDER BY s.created_at DESC `; return await db.query(sql, [studentId]); } static async findDetailsById(scoreId, studentId) { const sql = ` SELECT s.id, s.student_id, s.course_id, s.teacher_id, s.usual_score, s.midterm_score, s.final_score, s.total_score as score, s.grade_point, s.grade_level, s.created_at, s.remark, c.course_code, c.course_name, c.credit, c.semester, u.name as teacher_name, st.id as student_number, st.class as class_name FROM grades s JOIN courses c ON s.course_id = c.id JOIN users u ON s.teacher_id = u.id JOIN students st ON s.student_id = st.id WHERE s.id = ? AND st.id = ? `; const rows = await db.query(sql, [scoreId, studentId]); return rows[0]; } static async create(scoreData) { const { studentId, courseId, teacherId, score, gradePoint, gradeLevel, remark } = scoreData; // 既然TeacherService只传了score,我们默认把它作为 final_score 和 total_score // 如果需要支持平时分/期中分,需要修改前端和Controller const sql = ` INSERT INTO grades (student_id, course_id, teacher_id, final_score, total_score, grade_point, grade_level, created_at, remark) VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'), ?) `; const result = await db.pool.execute(sql, [ studentId, courseId, teacherId, score, score, gradePoint, gradeLevel, remark ]); return result[0].insertId; } static async findByStudentAndCourse(studentId, courseId) { const rows = await db.query( 'SELECT * FROM grades WHERE student_id = ? AND course_id = ?', [studentId, courseId] ); return rows[0]; } static async findByTeacher(teacherId, filters) { let sql = ` SELECT g.*, s.name as student_name, c.course_name FROM grades g JOIN students s ON g.student_id = s.id JOIN courses c ON g.course_id = c.id WHERE c.teacher_id = ? `; const params = [teacherId]; if (filters.courseId) { sql += ' AND g.course_id = ?'; params.push(filters.courseId); } if (filters.studentName) { sql += ' AND (s.name LIKE ? OR s.id LIKE ?)'; params.push(`%${filters.studentName}%`, `%${filters.studentName}%`); } return await db.query(sql, params); } static async findCourseStudentsWithGrades(courseId, teacherId) { const sql = ` SELECT s.id as student_id, s.name as student_name, g.usual_score, g.midterm_score, g.final_score, g.total_score, g.grade_point, g.grade_level, c.id as course_id, c.course_name FROM students s JOIN classes cl ON s.class = cl.class_name JOIN courses c ON c.class_id = cl.id LEFT JOIN grades g ON s.id = g.student_id AND g.course_id = c.id WHERE c.id = ? AND c.teacher_id = ? `; return await db.query(sql, [courseId, teacherId]); } static async upsert(scoreData) { const { studentId, courseId, teacherId, usual_score, midterm_score, final_score, score, gradePoint, gradeLevel, remark } = scoreData; const existing = await this.findByStudentAndCourse(studentId, courseId); // 处理参数:如果是 undefined 或空字符串,则设为 null const sanitize = (val) => (val === undefined || val === '' || val === null) ? null : val; const params = [ sanitize(usual_score), sanitize(midterm_score), sanitize(final_score), sanitize(score), sanitize(gradePoint), sanitize(gradeLevel), sanitize(remark) ]; if (existing) { const sql = `UPDATE grades SET usual_score=?, midterm_score=?, final_score=?, total_score=?, grade_point=?, grade_level=?, remark=? WHERE id=?`; await db.query(sql, [...params, existing.id]); return existing.id; } else { const sql = `INSERT INTO grades (student_id, course_id, teacher_id, usual_score, midterm_score, final_score, total_score, grade_point, grade_level, created_at, remark) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now', 'localtime'), ?)`; const insertParams = [ studentId, courseId, teacherId, ...params ]; const result = await db.query(sql, insertParams); return result.insertId; } } } module.exports = Score;