init
This commit is contained in:
419
serve/api/handlers/test_handler.go
Normal file
419
serve/api/handlers/test_handler.go
Normal file
@@ -0,0 +1,419 @@
|
||||
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": "删除成功"})
|
||||
}
|
||||
Reference in New Issue
Block a user