refactor(web): restructure Vue3 app layout
This commit is contained in:
140
memora-api/internal/handler/word.go
Normal file
140
memora-api/internal/handler/word.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"memora-api/internal/model"
|
||||
"memora-api/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type WordHandler struct {
|
||||
wordService *service.WordService
|
||||
}
|
||||
|
||||
func NewWordHandler(wordService *service.WordService) *WordHandler {
|
||||
return &WordHandler{wordService: wordService}
|
||||
}
|
||||
|
||||
// 添加单词(记忆模式)
|
||||
func (h *WordHandler) AddWord(c *gin.Context) {
|
||||
var req model.AddWordRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
// 调用有道API查询
|
||||
youdaoResp, err := h.wordService.QueryWord(req.Word)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "查询失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if youdaoResp.ErrorCode != "0" && youdaoResp.ErrorCode != "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("有道API错误: %s", youdaoResp.ErrorCode)})
|
||||
return
|
||||
}
|
||||
|
||||
// 保存到数据库
|
||||
word, err := h.wordService.SaveWord(req.Word, youdaoResp)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "保存失败: " + err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"message": "单词添加成功",
|
||||
"data": word,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取复习单词列表
|
||||
func (h *WordHandler) GetReviewWords(c *gin.Context) {
|
||||
mode := c.DefaultQuery("mode", "spelling")
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
||||
|
||||
words, err := h.wordService.GetReviewWords(mode, limit)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": words})
|
||||
}
|
||||
|
||||
// 提交复习答案
|
||||
func (h *WordHandler) SubmitReview(c *gin.Context) {
|
||||
var req model.ReviewAnswerRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
result, err := h.wordService.SubmitReviewAnswer(req)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": result})
|
||||
}
|
||||
|
||||
// 获取所有单词
|
||||
func (h *WordHandler) GetWords(c *gin.Context) {
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "20"))
|
||||
offset, _ := strconv.Atoi(c.DefaultQuery("offset", "0"))
|
||||
|
||||
words, total, err := h.wordService.GetAllWords(limit, offset)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"data": words,
|
||||
"total": total,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取统计信息
|
||||
func (h *WordHandler) GetStatistics(c *gin.Context) {
|
||||
stats, err := h.wordService.GetStatistics()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"data": stats})
|
||||
}
|
||||
|
||||
// 获取音频文件
|
||||
func (h *WordHandler) GetAudio(c *gin.Context) {
|
||||
word := c.Query("word")
|
||||
audioType := c.DefaultQuery("type", "uk")
|
||||
|
||||
if word == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "缺少word参数"})
|
||||
return
|
||||
}
|
||||
|
||||
// very small sanitization
|
||||
word = strings.TrimSpace(word)
|
||||
if word == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "word为空"})
|
||||
return
|
||||
}
|
||||
for _, r := range word {
|
||||
if !(r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z') {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "word包含非法字符"})
|
||||
return
|
||||
}
|
||||
}
|
||||
filename := word + "_" + audioType + ".mp3"
|
||||
path := "./audio/" + filename
|
||||
c.File(path)
|
||||
}
|
||||
Reference in New Issue
Block a user