实现共享试卷考试记录查看功能
功能说明: - 查看共享试卷的考试记录时,显示所有参与用户的成绩 - 按分数从高到低排序,方便查看排行 - 显示每个用户的头像、昵称和考试详情 实现细节: 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 <noreply@anthropic.com>
This commit is contained in:
parent
03f3e14f6e
commit
ccc77beef8
@ -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)
|
||||
|
||||
@ -443,6 +443,14 @@ const ExamManagement: React.FC = () => {
|
||||
style={{ marginBottom: 16 }}
|
||||
size="small"
|
||||
>
|
||||
{record.user && (
|
||||
<div style={{ marginBottom: 12, display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<Avatar src={record.user.avatar} icon={<UserOutlined />} />
|
||||
<span style={{ fontWeight: 'bold' }}>
|
||||
{record.user.nickname || record.user.username}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<Descriptions column={1} size="small">
|
||||
<Descriptions.Item label="状态">
|
||||
{record.status === 'in_progress' && <Tag color="processing">进行中</Tag>}
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user