package models import ( "time" "gorm.io/gorm" ) // WrongQuestion 错题记录 type WrongQuestion struct { ID int64 `gorm:"primarykey" json:"id"` UserID int64 `gorm:"index;not null" json:"user_id"` QuestionID int64 `gorm:"index;not null" json:"question_id"` FirstWrongTime time.Time `json:"first_wrong_time"` LastWrongTime time.Time `json:"last_wrong_time"` TotalWrongCount int `gorm:"default:1" json:"total_wrong_count"` MasteryLevel int `gorm:"default:0" json:"mastery_level"` // 0-100 ConsecutiveCorrect int `gorm:"default:0" json:"consecutive_correct"` IsMastered bool `gorm:"default:false" json:"is_mastered"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 关联 PracticeQuestion *PracticeQuestion `gorm:"foreignKey:QuestionID;references:ID" json:"question,omitempty"` History []WrongQuestionHistory `gorm:"foreignKey:WrongQuestionID" json:"history,omitempty"` } // WrongQuestionHistory 错误历史记录 type WrongQuestionHistory struct { ID int64 `gorm:"primarykey" json:"id"` WrongQuestionID int64 `gorm:"index;not null" json:"wrong_question_id"` UserAnswer string `gorm:"type:jsonb;not null" json:"user_answer"` // JSON 存储 CorrectAnswer string `gorm:"type:jsonb;not null" json:"correct_answer"` // JSON 存储 AnsweredAt time.Time `gorm:"index" json:"answered_at"` TimeSpent int `json:"time_spent"` // 答题用时(秒) IsCorrect bool `json:"is_correct"` } // TableName 指定表名 func (WrongQuestion) TableName() string { return "wrong_questions" } // TableName 指定表名 func (WrongQuestionHistory) TableName() string { return "wrong_question_history" } // WrongQuestionDTO 错题数据传输对象 type WrongQuestionDTO struct { ID int64 `json:"id"` QuestionID int64 `json:"question_id"` Question *PracticeQuestionDTO `json:"question"` FirstWrongTime time.Time `json:"first_wrong_time"` LastWrongTime time.Time `json:"last_wrong_time"` TotalWrongCount int `json:"total_wrong_count"` MasteryLevel int `json:"mastery_level"` ConsecutiveCorrect int `json:"consecutive_correct"` IsMastered bool `json:"is_mastered"` RecentHistory []WrongQuestionHistoryDTO `json:"recent_history,omitempty"` // 最近3次历史 } // WrongQuestionHistoryDTO 错误历史 DTO type WrongQuestionHistoryDTO struct { ID int64 `json:"id"` UserAnswer interface{} `json:"user_answer"` CorrectAnswer interface{} `json:"correct_answer"` AnsweredAt time.Time `json:"answered_at"` TimeSpent int `json:"time_spent"` IsCorrect bool `json:"is_correct"` } // WrongQuestionStats 错题统计 type WrongQuestionStats struct { TotalWrong int `json:"total_wrong"` // 总错题数 Mastered int `json:"mastered"` // 已掌握数 NotMastered int `json:"not_mastered"` // 未掌握数 NeedReview int `json:"need_review"` // 需要复习数 TypeStats map[string]int `json:"type_stats"` // 按题型统计 CategoryStats map[string]int `json:"category_stats"` // 按分类统计 MasteryLevelDist map[string]int `json:"mastery_level_dist"` // 掌握度分布 TrendData []TrendPoint `json:"trend_data"` // 错题趋势 } // TrendPoint 趋势数据点 type TrendPoint struct { Date string `json:"date"` Count int `json:"count"` } // RecordWrongAnswer 记录错误答案 func (wq *WrongQuestion) RecordWrongAnswer() { now := time.Now() if wq.FirstWrongTime.IsZero() { wq.FirstWrongTime = now } wq.LastWrongTime = now wq.TotalWrongCount++ wq.ConsecutiveCorrect = 0 // 重置连续答对次数 wq.IsMastered = false // 重新标记为未掌握 wq.MasteryLevel = 0 // 重置掌握度 } // RecordCorrectAnswer 记录正确答案 func (wq *WrongQuestion) RecordCorrectAnswer() { wq.ConsecutiveCorrect++ // 根据连续答对次数更新掌握度(每答对一次增加16.67%) // 连续答对6次即达到100% wq.MasteryLevel = (wq.ConsecutiveCorrect * 100) / 6 if wq.MasteryLevel > 100 { wq.MasteryLevel = 100 } // 连续答对6次标记为已掌握 if wq.ConsecutiveCorrect >= 6 { wq.IsMastered = true wq.MasteryLevel = 100 } }