From ccc77beef8744c5a669fd02e9ed7bf2b95b31d51 Mon Sep 17 00:00:00 2001 From: yanlongqi Date: Mon, 1 Dec 2025 21:34:20 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=85=B1=E4=BA=AB=E8=AF=95?= =?UTF-8?q?=E5=8D=B7=E8=80=83=E8=AF=95=E8=AE=B0=E5=BD=95=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 功能说明: - 查看共享试卷的考试记录时,显示所有参与用户的成绩 - 按分数从高到低排序,方便查看排行 - 显示每个用户的头像、昵称和考试详情 实现细节: 1. 后端:修改 GetExamRecordList 接口 - 指定试卷ID时自动识别共享关系 - 查询原始试卷+所有分享副本的考试记录 - 返回用户信息(username, nickname, avatar) - 按分数降序排序 2. 前端:更新考试记录展示 - 显示用户头像和昵称 - 保持原有的考试详情信息 - 适配共享和非共享两种场景 修改文件: - internal/handlers/exam_handler.go: 重构GetExamRecordList逻辑 - web/src/types/exam.ts: ExamRecord添加user字段 - web/src/pages/ExamManagement.tsx: 显示用户信息 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- internal/handlers/exam_handler.go | 61 +++++++++++++++++++++++++++++-- web/src/pages/ExamManagement.tsx | 8 ++++ web/src/types/exam.ts | 6 +++ 3 files changed, 71 insertions(+), 4 deletions(-) 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 }