Files
ai_english/serve/api/handlers/test_handler.go

420 lines
12 KiB
Go
Raw Normal View History

2025-11-17 13:39:05 +08:00
package handlers
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/common"
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/models"
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/services"
"github.com/Nanqipro/YunQue-Tech-Projects/ai_english_learning/serve/internal/utils"
)
// TestHandler 测试处理器
type TestHandler struct {
testService *services.TestService
}
// NewTestHandler 创建测试处理器实例
func NewTestHandler(testService *services.TestService) *TestHandler {
return &TestHandler{
testService: testService,
}
}
// GetTestTemplates 获取测试模板列表
// @Summary 获取测试模板列表
// @Tags Test
// @Param type query string false "测试类型"
// @Param difficulty query string false "难度"
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/templates [get]
func (h *TestHandler) GetTestTemplates(c *gin.Context) {
typeStr := c.Query("type")
difficultyStr := c.Query("difficulty")
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "20"))
var testType *models.TestType
if typeStr != "" {
t := models.TestType(typeStr)
testType = &t
}
var difficulty *models.TestDifficulty
if difficultyStr != "" {
d := models.TestDifficulty(difficultyStr)
difficulty = &d
}
templates, total, err := h.testService.GetTestTemplates(testType, difficulty, page, pageSize)
if err != nil {
common.ErrorResponse(c, http.StatusInternalServerError, "获取测试模板失败")
return
}
common.SuccessResponse(c, gin.H{
"templates": templates,
"pagination": gin.H{
"page": page,
"page_size": pageSize,
"total": total,
"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
},
})
}
// GetTestTemplateByID 获取测试模板详情
// @Summary 获取测试模板详情
// @Tags Test
// @Param id path string true "模板ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/templates/{id} [get]
func (h *TestHandler) GetTestTemplateByID(c *gin.Context) {
id := c.Param("id")
template, err := h.testService.GetTestTemplateByID(id)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试模板不存在")
return
}
common.SuccessResponse(c, gin.H{"data": template})
}
// CreateTestSession 创建测试会话
// @Summary 创建测试会话
// @Tags Test
// @Param body body object true "请求体"
// @Success 201 {object} common.Response
// @Router /api/v1/tests/sessions [post]
func (h *TestHandler) CreateTestSession(c *gin.Context) {
userID, exists := utils.GetUserIDFromContext(c)
if !exists {
common.BadRequestResponse(c, "请先登录")
return
}
var req struct {
TemplateID string `json:"template_id" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
common.BadRequestResponse(c, "请求参数错误")
return
}
session, err := h.testService.CreateTestSession(req.TemplateID, utils.Int64ToString(userID))
if err != nil {
common.ErrorResponse(c, http.StatusInternalServerError, "创建测试会话失败: "+err.Error())
return
}
common.SuccessResponseWithStatus(c, http.StatusCreated, gin.H{"data": session})
}
// GetTestSession 获取测试会话
// @Summary 获取测试会话
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id} [get]
func (h *TestHandler) GetTestSession(c *gin.Context) {
sessionID := c.Param("id")
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
// 验证用户权限
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权访问此测试会话")
return
}
common.SuccessResponse(c, gin.H{"data": session})
}
// StartTest 开始测试
// @Summary 开始测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/start [put]
func (h *TestHandler) StartTest(c *gin.Context) {
sessionID := c.Param("id")
// 验证用户权限
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
return
}
updatedSession, err := h.testService.StartTest(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
common.SuccessResponse(c, gin.H{"data": updatedSession})
}
// SubmitAnswer 提交答案
// @Summary 提交答案
// @Tags Test
// @Param id path string true "会话ID"
// @Param body body object true "请求体"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/answers [post]
func (h *TestHandler) SubmitAnswer(c *gin.Context) {
sessionID := c.Param("id")
var req struct {
QuestionID string `json:"question_id" binding:"required"`
Answer string `json:"answer" binding:"required"`
}
if err := c.ShouldBindJSON(&req); err != nil {
common.BadRequestResponse(c, "请求参数错误")
return
}
// 验证用户权限
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
return
}
updatedSession, err := h.testService.SubmitAnswer(sessionID, req.QuestionID, req.Answer)
if err != nil {
common.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
common.SuccessResponse(c, gin.H{"data": updatedSession})
}
// PauseTest 暂停测试
// @Summary 暂停测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/pause [put]
func (h *TestHandler) PauseTest(c *gin.Context) {
sessionID := c.Param("id")
// 验证用户权限
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
return
}
updatedSession, err := h.testService.PauseTest(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
common.SuccessResponse(c, gin.H{"data": updatedSession})
}
// ResumeTest 恢复测试
// @Summary 恢复测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/resume [put]
func (h *TestHandler) ResumeTest(c *gin.Context) {
sessionID := c.Param("id")
// 验证用户权限
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
return
}
updatedSession, err := h.testService.ResumeTest(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
common.SuccessResponse(c, gin.H{"data": updatedSession})
}
// CompleteTest 完成测试
// @Summary 完成测试
// @Tags Test
// @Param id path string true "会话ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions/{id}/complete [put]
func (h *TestHandler) CompleteTest(c *gin.Context) {
sessionID := c.Param("id")
// 验证用户权限
session, err := h.testService.GetTestSession(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试会话不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if session.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权操作此测试会话")
return
}
result, err := h.testService.CompleteTest(sessionID)
if err != nil {
common.ErrorResponse(c, http.StatusBadRequest, err.Error())
return
}
common.SuccessResponse(c, gin.H{"data": result})
}
// GetUserTestHistory 获取用户测试历史
// @Summary 获取用户测试历史
// @Tags Test
// @Param page query int false "页码"
// @Param page_size query int false "每页数量"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/sessions [get]
func (h *TestHandler) GetUserTestHistory(c *gin.Context) {
userID, exists := utils.GetUserIDFromContext(c)
if !exists {
common.BadRequestResponse(c, "请先登录")
return
}
page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10"))
results, total, err := h.testService.GetUserTestHistory(utils.Int64ToString(userID), page, pageSize)
if err != nil {
common.ErrorResponse(c, http.StatusInternalServerError, "获取测试历史失败")
return
}
common.SuccessResponse(c, gin.H{
"sessions": results,
"pagination": gin.H{
"page": page,
"page_size": pageSize,
"total": total,
"total_page": (total + int64(pageSize) - 1) / int64(pageSize),
},
})
}
// GetTestResultByID 获取测试结果详情
// @Summary 获取测试结果详情
// @Tags Test
// @Param id path string true "结果ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/results/{id} [get]
func (h *TestHandler) GetTestResultByID(c *gin.Context) {
resultID := c.Param("id")
result, err := h.testService.GetTestResultByID(resultID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试结果不存在")
return
}
// 验证用户权限
userID, _ := utils.GetUserIDFromContext(c)
if result.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权访问此测试结果")
return
}
common.SuccessResponse(c, gin.H{"data": result})
}
// GetUserTestStats 获取用户测试统计
// @Summary 获取用户测试统计
// @Tags Test
// @Success 200 {object} common.Response
// @Router /api/v1/tests/stats [get]
func (h *TestHandler) GetUserTestStats(c *gin.Context) {
userID, exists := utils.GetUserIDFromContext(c)
if !exists {
common.BadRequestResponse(c, "请先登录")
return
}
stats, err := h.testService.GetUserTestStats(utils.Int64ToString(userID))
if err != nil {
common.ErrorResponse(c, http.StatusInternalServerError, "获取测试统计失败")
return
}
common.SuccessResponse(c, stats)
}
// DeleteTestResult 删除测试结果
// @Summary 删除测试结果
// @Tags Test
// @Param id path string true "结果ID"
// @Success 200 {object} common.Response
// @Router /api/v1/tests/results/{id} [delete]
func (h *TestHandler) DeleteTestResult(c *gin.Context) {
resultID := c.Param("id")
// 验证用户权限
result, err := h.testService.GetTestResultByID(resultID)
if err != nil {
common.ErrorResponse(c, http.StatusNotFound, "测试结果不存在")
return
}
userID, _ := utils.GetUserIDFromContext(c)
if result.UserID != utils.Int64ToString(userID) {
common.ErrorResponse(c, http.StatusForbidden, "无权删除此测试结果")
return
}
if err := h.testService.DeleteTestResult(resultID); err != nil {
common.ErrorResponse(c, http.StatusInternalServerError, "删除测试结果失败")
return
}
common.SuccessResponse(c, gin.H{"message": "删除成功"})
}