diff --git a/internal/handlers/exam_handler.go b/internal/handlers/exam_handler.go index 16982df..7855e57 100644 --- a/internal/handlers/exam_handler.go +++ b/internal/handlers/exam_handler.go @@ -641,20 +641,73 @@ func GetExamRecordList(c *gin.Context) { examIDStr := c.Query("exam_id") db := database.GetDB() - query := db.Where("user_id = ?", userID) - // 如果指定了试卷ID,只查询该试卷的记录 + // 如果指定了试卷ID,需要判断是否为共享试卷 if examIDStr != "" { examID, err := strconv.ParseUint(examIDStr, 10, 32) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"success": false, "message": "无效的试卷ID"}) return } - query = query.Where("exam_id = ?", examID) + + // 查询试卷信息 + var exam models.Exam + if err := db.Where("id = ? AND user_id = ?", examID, userID).First(&exam).Error; err != nil { + c.JSON(http.StatusNotFound, gin.H{"success": false, "message": "试卷不存在或无权限"}) + return + } + + // 获取所有相关试卷ID(包括原始试卷和所有分享副本) + var relatedExamIDs []uint + relatedExamIDs = append(relatedExamIDs, uint(examID)) + + // 如果这是被分享的试卷,找到原始试卷 + if exam.IsShared && exam.SharedByID != nil { + var originalExam models.Exam + if err := db.Where("user_id = ? AND question_ids = ? AND deleted_at IS NULL", + *exam.SharedByID, exam.QuestionIDs).First(&originalExam).Error; err == nil { + relatedExamIDs = append(relatedExamIDs, originalExam.ID) + } + } + + // 查找所有基于该试卷的分享副本 + var sharedExams []models.Exam + sharedByID := exam.UserID + if exam.IsShared && exam.SharedByID != nil { + sharedByID = *exam.SharedByID + } + if err := db.Where("shared_by_id = ? AND question_ids = ? AND deleted_at IS NULL", + sharedByID, exam.QuestionIDs).Find(&sharedExams).Error; err == nil { + for _, se := range sharedExams { + relatedExamIDs = append(relatedExamIDs, se.ID) + } + } + + // 查询所有相关试卷的考试记录(包含用户信息) + var records []models.ExamRecord + if err := db.Where("exam_id IN ? AND status = ?", relatedExamIDs, "graded"). + Preload("Exam"). + Preload("User", func(db *gorm.DB) *gorm.DB { + return db.Select("id", "username", "nickname", "avatar") + }). + Order("score DESC, created_at DESC"). + Find(&records).Error; err != nil { + log.Printf("查询考试记录失败: %v", err) + c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "查询考试记录失败"}) + return + } + + c.JSON(http.StatusOK, gin.H{ + "success": true, + "data": records, + }) + return } + // 如果没有指定试卷ID,只返回当前用户的记录 var records []models.ExamRecord - if err := query.Preload("Exam"). + if err := db.Where("user_id = ?", userID). + Preload("Exam"). Order("created_at DESC"). Find(&records).Error; err != nil { log.Printf("查询考试记录失败: %v", err) diff --git a/web/src/pages/ExamManagement.tsx b/web/src/pages/ExamManagement.tsx index a0313f9..d1ed5c0 100644 --- a/web/src/pages/ExamManagement.tsx +++ b/web/src/pages/ExamManagement.tsx @@ -443,6 +443,14 @@ const ExamManagement: React.FC = () => { style={{ marginBottom: 16 }} size="small" > + {record.user && ( +
+ } /> + + {record.user.nickname || record.user.username} + +
+ )} {record.status === 'in_progress' && 进行中} diff --git a/web/src/types/exam.ts b/web/src/types/exam.ts index 877f2df..ddaf1e6 100644 --- a/web/src/types/exam.ts +++ b/web/src/types/exam.ts @@ -61,6 +61,12 @@ export interface ExamRecord { status: 'in_progress' | 'submitted' | 'graded' is_passed: boolean exam?: ExamModel + user?: { // 用户信息(共享试卷时返回) + id: number + username: string + nickname: string + avatar: string + } created_at: string updated_at: string }