diff --git a/memora-api/internal/handler/word.go b/memora-api/internal/handler/word.go index 4696235..92d704e 100644 --- a/memora-api/internal/handler/word.go +++ b/memora-api/internal/handler/word.go @@ -6,7 +6,7 @@ import ( "strconv" "strings" - "memora-api/internal/model" + "memora-api/internal/request" "memora-api/internal/service" "github.com/gin-gonic/gin" @@ -22,7 +22,7 @@ func NewWordHandler(wordService *service.WordService) *WordHandler { // 添加单词(记忆模式) func (h *WordHandler) AddWord(c *gin.Context) { - var req model.AddWordRequest + var req request.AddWordRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return @@ -69,7 +69,7 @@ func (h *WordHandler) GetReviewWords(c *gin.Context) { // 提交复习答案 func (h *WordHandler) SubmitReview(c *gin.Context) { - var req model.ReviewAnswerRequest + var req request.ReviewAnswerRequest if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return diff --git a/memora-api/internal/model/memory_record.go b/memora-api/internal/model/memory_record.go new file mode 100644 index 0000000..5884ec5 --- /dev/null +++ b/memora-api/internal/model/memory_record.go @@ -0,0 +1,21 @@ +package model + +import "time" + +type MemoryRecord struct { + ID int64 `json:"id" gorm:"primaryKey"` + WordID int64 `json:"word_id" gorm:"index;not null"` + UserID int64 `json:"user_id" gorm:"index;default:1"` + CorrectCount int `json:"correct_count" gorm:"default:0"` + TotalCount int `json:"total_count" gorm:"default:0"` + MasteryLevel int `json:"mastery_level" gorm:"default:0"` + LastReviewedAt *time.Time `json:"last_reviewed_at"` + NextReviewAt *time.Time `json:"next_review_at" gorm:"index"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Word *Word `json:"word,omitempty" gorm:"foreignKey:WordID"` +} + +func (MemoryRecord) TableName() string { + return "memory_records" +} diff --git a/memora-api/internal/model/model.go b/memora-api/internal/model/model.go deleted file mode 100644 index fe4695e..0000000 --- a/memora-api/internal/model/model.go +++ /dev/null @@ -1,87 +0,0 @@ -package model - -import ( - "time" -) - -type Word struct { - ID int64 `json:"id" gorm:"primaryKey"` - Word string `json:"word" gorm:"size:100;uniqueIndex;not null"` - PhoneticUK string `json:"phonetic_uk" gorm:"size:255"` - PhoneticUS string `json:"phonetic_us" gorm:"size:255"` - AudioUK string `json:"audio_uk" gorm:"size:500"` - AudioUS string `json:"audio_us" gorm:"size:500"` - PartOfSpeech string `json:"part_of_speech" gorm:"size:50"` - Definition string `json:"definition" gorm:"type:text"` - ExampleSentence string `json:"example_sentence" gorm:"type:text"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` -} - -func (Word) TableName() string { - return "words" -} - -type MemoryRecord struct { - ID int64 `json:"id" gorm:"primaryKey"` - WordID int64 `json:"word_id" gorm:"index;not null"` - UserID int64 `json:"user_id" gorm:"index;default:1"` - CorrectCount int `json:"correct_count" gorm:"default:0"` - TotalCount int `json:"total_count" gorm:"default:0"` - MasteryLevel int `json:"mastery_level" gorm:"default:0"` - LastReviewedAt *time.Time `json:"last_reviewed_at"` - NextReviewAt *time.Time `json:"next_review_at" gorm:"index"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Word *Word `json:"word,omitempty" gorm:"foreignKey:WordID"` -} - -func (MemoryRecord) TableName() string { - return "memory_records" -} - -// 请求响应结构 -type AddWordRequest struct { - Word string `json:"word" binding:"required"` -} - -type ReviewAnswerRequest struct { - RecordID int64 `json:"record_id" binding:"required"` - Answer string `json:"answer" binding:"required"` - Mode string `json:"mode" binding:"required"` // spelling, en2cn, cn2en -} - -type ReviewResult struct { - Word *Word `json:"word"` - Correct bool `json:"correct"` - Answer string `json:"answer"` - CorrectAns string `json:"correct_ans,omitempty"` -} - -// 有道API响应 (标准API) -type YoudaoResponse struct { - Query string `json:"query"` - Translation []string `json:"translation"` - Basic struct { - Phonetic string `json:"phonetic"` - UkPhonetic string `json:"uk-phonetic"` - UsPhonetic string `json:"us-phonetic"` - ExamType []string `json:"exam_type"` - Wfs []struct { - Wf struct { - Name string `json:"name"` - } `json:"wf"` - Means []struct { - Mean struct { - Text string `json:"text"` - } `json:"mean"` - } `json:"means"` - } `json:"wfs"` - } `json:"basic"` - SpeakUrl string `json:"speakUrl"` - SpeakFile string `json:"speakFile"` - Web []struct { - Value []string `json:"value"` - } `json:"web"` - ErrorCode string `json:"errorCode"` -} diff --git a/memora-api/internal/model/word.go b/memora-api/internal/model/word.go new file mode 100644 index 0000000..352e138 --- /dev/null +++ b/memora-api/internal/model/word.go @@ -0,0 +1,21 @@ +package model + +import "time" + +type Word struct { + ID int64 `json:"id" gorm:"primaryKey"` + Word string `json:"word" gorm:"size:100;uniqueIndex;not null"` + PhoneticUK string `json:"phonetic_uk" gorm:"size:255"` + PhoneticUS string `json:"phonetic_us" gorm:"size:255"` + AudioUK string `json:"audio_uk" gorm:"size:500"` + AudioUS string `json:"audio_us" gorm:"size:500"` + PartOfSpeech string `json:"part_of_speech" gorm:"size:50"` + Definition string `json:"definition" gorm:"type:text"` + ExampleSentence string `json:"example_sentence" gorm:"type:text"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` +} + +func (Word) TableName() string { + return "words" +} diff --git a/memora-api/internal/model/youdao.go b/memora-api/internal/model/youdao.go new file mode 100644 index 0000000..322ad57 --- /dev/null +++ b/memora-api/internal/model/youdao.go @@ -0,0 +1,28 @@ +package model + +type YoudaoResponse struct { + Query string `json:"query"` + Translation []string `json:"translation"` + Basic struct { + Phonetic string `json:"phonetic"` + UkPhonetic string `json:"uk-phonetic"` + UsPhonetic string `json:"us-phonetic"` + ExamType []string `json:"exam_type"` + Wfs []struct { + Wf struct { + Name string `json:"name"` + } `json:"wf"` + Means []struct { + Mean struct { + Text string `json:"text"` + } `json:"mean"` + } `json:"means"` + } `json:"wfs"` + } `json:"basic"` + SpeakUrl string `json:"speakUrl"` + SpeakFile string `json:"speakFile"` + Web []struct { + Value []string `json:"value"` + } `json:"web"` + ErrorCode string `json:"errorCode"` +} diff --git a/memora-api/internal/request/word.go b/memora-api/internal/request/word.go new file mode 100644 index 0000000..cbff434 --- /dev/null +++ b/memora-api/internal/request/word.go @@ -0,0 +1,11 @@ +package request + +type AddWordRequest struct { + Word string `json:"word" binding:"required"` +} + +type ReviewAnswerRequest struct { + RecordID int64 `json:"record_id" binding:"required"` + Answer string `json:"answer" binding:"required"` + Mode string `json:"mode" binding:"required"` // spelling, en2cn, cn2en +} diff --git a/memora-api/internal/response/word.go b/memora-api/internal/response/word.go new file mode 100644 index 0000000..3d734e7 --- /dev/null +++ b/memora-api/internal/response/word.go @@ -0,0 +1,10 @@ +package response + +import "memora-api/internal/model" + +type ReviewResult struct { + Word *model.Word `json:"word"` + Correct bool `json:"correct"` + Answer string `json:"answer"` + CorrectAns string `json:"correct_ans,omitempty"` +} diff --git a/memora-api/internal/service/word.go b/memora-api/internal/service/word.go index 18a1129..ec31b1d 100644 --- a/memora-api/internal/service/word.go +++ b/memora-api/internal/service/word.go @@ -15,6 +15,8 @@ import ( "memora-api/internal/config" "memora-api/internal/model" + "memora-api/internal/request" + "memora-api/internal/response" "gorm.io/gorm" ) @@ -359,7 +361,7 @@ func containsAny(def string, ans string) bool { } // 提交复习答案 -func (s *WordService) SubmitReviewAnswer(req model.ReviewAnswerRequest) (*model.ReviewResult, error) { +func (s *WordService) SubmitReviewAnswer(req request.ReviewAnswerRequest) (*response.ReviewResult, error) { var record model.MemoryRecord if err := s.db.Preload("Word").Where("id = ?", req.RecordID).First(&record).Error; err != nil { return nil, err @@ -387,7 +389,7 @@ func (s *WordService) SubmitReviewAnswer(req model.ReviewAnswerRequest) (*model. // 更新记忆记录 s.updateMemoryRecord(record.WordID, correct) - return &model.ReviewResult{ + return &response.ReviewResult{ Word: word, Correct: correct, Answer: req.Answer, @@ -422,9 +424,9 @@ func (s *WordService) GetStatistics() (map[string]interface{}, error) { s.db.Model(&model.MemoryRecord{}).Where("last_reviewed_at >= ?", time.Now().Format("2006-01-02")).Count(&todayReviewed) return map[string]interface{}{ - "total_words": totalWords, - "mastered_words": masteredWords, - "need_review": needReview, - "today_reviewed": todayReviewed, + "total_words": totalWords, + "mastered_words": masteredWords, + "need_review": needReview, + "today_reviewed": todayReviewed, }, nil }