init
This commit is contained in:
276
serve/internal/handler/speaking_handler.go
Normal file
276
serve/internal/handler/speaking_handler.go
Normal file
@@ -0,0 +1,276 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/services"
|
||||
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
|
||||
)
|
||||
|
||||
type SpeakingHandler struct {
|
||||
speakingService *services.SpeakingService
|
||||
}
|
||||
|
||||
func NewSpeakingHandler(speakingService *services.SpeakingService) *SpeakingHandler {
|
||||
return &SpeakingHandler{speakingService: speakingService}
|
||||
}
|
||||
|
||||
// GetSpeakingScenarios 获取口语场景列表
|
||||
func (h *SpeakingHandler) GetSpeakingScenarios(c *gin.Context) {
|
||||
level := c.Query("level")
|
||||
category := c.Query("category")
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
|
||||
scenarios, total, err := h.speakingService.GetSpeakingScenarios(level, category, page, pageSize)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"scenarios": scenarios, "total": total})
|
||||
}
|
||||
|
||||
// GetSpeakingScenario 获取单个口语场景
|
||||
func (h *SpeakingHandler) GetSpeakingScenario(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
scenario, err := h.speakingService.GetSpeakingScenario(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Speaking scenario not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"scenario": scenario})
|
||||
}
|
||||
|
||||
// CreateSpeakingScenario 创建口语场景
|
||||
func (h *SpeakingHandler) CreateSpeakingScenario(c *gin.Context) {
|
||||
var scenario models.SpeakingScenario
|
||||
if err := c.ShouldBindJSON(&scenario); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.speakingService.CreateSpeakingScenario(&scenario); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"scenario": scenario})
|
||||
}
|
||||
|
||||
// UpdateSpeakingScenario 更新口语场景
|
||||
func (h *SpeakingHandler) UpdateSpeakingScenario(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var updates models.SpeakingScenario
|
||||
if err := c.ShouldBindJSON(&updates); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.speakingService.UpdateSpeakingScenario(id, &updates); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
scenario, err := h.speakingService.GetSpeakingScenario(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"scenario": scenario})
|
||||
}
|
||||
|
||||
// DeleteSpeakingScenario 删除口语场景
|
||||
func (h *SpeakingHandler) DeleteSpeakingScenario(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
if err := h.speakingService.DeleteSpeakingScenario(id); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Speaking scenario deleted successfully"})
|
||||
}
|
||||
|
||||
// SearchSpeakingScenarios 搜索口语场景
|
||||
func (h *SpeakingHandler) SearchSpeakingScenarios(c *gin.Context) {
|
||||
keyword := c.Query("keyword")
|
||||
level := c.Query("level")
|
||||
category := c.Query("category")
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
|
||||
scenarios, total, err := h.speakingService.SearchSpeakingScenarios(keyword, level, category, page, pageSize)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"scenarios": scenarios, "total": total})
|
||||
}
|
||||
|
||||
// GetRecommendedScenarios 获取推荐口语场景
|
||||
func (h *SpeakingHandler) GetRecommendedScenarios(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
limit, _ := strconv.Atoi(c.DefaultQuery("limit", "5"))
|
||||
|
||||
scenarios, err := h.speakingService.GetRecommendedScenarios(userID, limit)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"scenarios": scenarios})
|
||||
}
|
||||
|
||||
// CreateSpeakingRecord 创建口语记录
|
||||
func (h *SpeakingHandler) CreateSpeakingRecord(c *gin.Context) {
|
||||
var record models.SpeakingRecord
|
||||
if err := c.ShouldBindJSON(&record); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
record.UserID = c.GetString("user_id")
|
||||
if err := h.speakingService.CreateSpeakingRecord(&record); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusCreated, gin.H{"record": record})
|
||||
}
|
||||
|
||||
// UpdateSpeakingRecord 更新口语记录
|
||||
func (h *SpeakingHandler) UpdateSpeakingRecord(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var updates models.SpeakingRecord
|
||||
if err := c.ShouldBindJSON(&updates); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
if err := h.speakingService.UpdateSpeakingRecord(id, &updates); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
record, err := h.speakingService.GetSpeakingRecord(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"record": record})
|
||||
}
|
||||
|
||||
// GetSpeakingRecord 获取口语记录详情
|
||||
func (h *SpeakingHandler) GetSpeakingRecord(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
record, err := h.speakingService.GetSpeakingRecord(id)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Speaking record not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"record": record})
|
||||
}
|
||||
|
||||
// GetUserSpeakingRecords 获取用户口语记录列表
|
||||
func (h *SpeakingHandler) GetUserSpeakingRecords(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
|
||||
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
|
||||
|
||||
records, total, err := h.speakingService.GetUserSpeakingRecords(userID, page, pageSize)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"records": records,
|
||||
"total": total,
|
||||
})
|
||||
}
|
||||
|
||||
// SubmitSpeaking 提交口语练习
|
||||
func (h *SpeakingHandler) SubmitSpeaking(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var req struct {
|
||||
AudioURL string `json:"audio_url"`
|
||||
Transcript string `json:"transcript"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.speakingService.SubmitSpeaking(id, req.AudioURL, req.Transcript); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Speaking submitted successfully"})
|
||||
}
|
||||
|
||||
// GradeSpeaking AI评分口语练习
|
||||
func (h *SpeakingHandler) GradeSpeaking(c *gin.Context) {
|
||||
id := c.Param("id")
|
||||
|
||||
var req struct {
|
||||
Pronunciation float64 `json:"pronunciation"`
|
||||
Fluency float64 `json:"fluency"`
|
||||
Accuracy float64 `json:"accuracy"`
|
||||
Score float64 `json:"score"`
|
||||
Feedback string `json:"feedback"`
|
||||
Suggestions string `json:"suggestions"`
|
||||
}
|
||||
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.speakingService.GradeSpeaking(id, req.Pronunciation, req.Fluency, req.Accuracy, req.Score, req.Feedback, req.Suggestions); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"message": "Speaking graded successfully"})
|
||||
}
|
||||
|
||||
// GetUserSpeakingStats 获取用户口语统计
|
||||
func (h *SpeakingHandler) GetUserSpeakingStats(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
|
||||
stats, err := h.speakingService.GetUserSpeakingStats(userID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"stats": stats})
|
||||
}
|
||||
|
||||
// GetSpeakingProgress 获取口语进度
|
||||
func (h *SpeakingHandler) GetSpeakingProgress(c *gin.Context) {
|
||||
userID := c.GetString("user_id")
|
||||
scenarioID := c.Param("scenario_id")
|
||||
|
||||
progress, err := h.speakingService.GetSpeakingProgress(userID, scenarioID)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Speaking progress not found"})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"progress": progress})
|
||||
}
|
||||
Reference in New Issue
Block a user