package controllers import ( "encoding/json" "fmt" "net/http" "strconv" "time" "learnsteam/cslms-api/internal/models" "learnsteam/cslms-api/internal/services" "github.com/gin-gonic/gin" "github.com/google/go-cmp/cmp" "github.com/google/uuid" "gorm.io/datatypes" ) type UserQuizController interface { List(*gin.Context) Find(*gin.Context) Create(*gin.Context) Update(*gin.Context) Answer(*gin.Context) } type userQuizController struct { service services.UserQuizService quizService services.QuizService userquizpaperService services.UserQuizPaperService } func NewUserQuizController(service services.UserQuizService, quizService services.QuizService, userquizpaperService services.UserQuizPaperService) UserQuizController { return &userQuizController{ service: service, quizService: quizService, userquizpaperService: userquizpaperService, } } // UserQuiz List // // @Summary 사용자퀴즈 목록 가져오기 // @Description 사용자퀴즈 목록을 가져옵니다. // @Tags 사용자퀴즈 // // @Accept json // @Produce json // // @Security Bearer // // @Param user_quiz_paper_id query string true "사용자퀴즈페이퍼 ID" // @Param q query string false "검색어" // @Param page query int false "페이지" // @Param limit query int false "페이지 사이즈" // // @Success 200 {object} models.UserQuizListResponse // @Router /userquiz [get] func (controller *userQuizController) List(c *gin.Context) { quiz_paper_id, err := strconv.ParseInt(c.DefaultQuery("user_quiz_paper_id", ""), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } page, err := strconv.Atoi(c.DefaultQuery("page", "1")) if err != nil { fmt.Println("error : page") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } limit, err := strconv.Atoi(c.DefaultQuery("limit", "10")) if err != nil { fmt.Println("error : limit") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } result, err := controller.service.List(quiz_paper_id, page, limit) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } totalNumber, err := controller.service.Total(quiz_paper_id) if err != nil { fmt.Println("error : list") c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } totalPage := int64(totalNumber/int64(limit) + 1) c.JSON(http.StatusOK, gin.H{"data": result, "total": totalNumber, "page": page, "totalPage": totalPage, "pageSize": limit}) } // Get UserQuiz // // @Summary 사용자퀴즈 가져오기 // @Description ID로 사용자퀴즈를 가져옵니다. // @Tags 사용자퀴즈 // // @Accept json // @Produce json // // @Security Bearer // // @Param id path string true "사용자퀴즈 ID" // // @Success 200 {object} models.UserQuizResponse // @Router /userquiz/{id} [get] func (controller *userQuizController) Find(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } result, err := controller.service.Find(id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, result) } // Create Quiz // // @Summary 사용자퀴즈 생성 // @Description 사용자퀴즈를 만듭니다. // @Tags 사용자퀴즈 // // @Accept json // @Produce json // // @Security Bearer // // @Param quizBody body models.UserQuizRequest true "UserQuiz Body" // // @Success 200 {object} models.UserQuizResponse // @Router /userquiz [post] func (controller *userQuizController) Create(c *gin.Context) { var request models.UserQuizRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var content datatypes.JSON content, err := json.Marshal(request.Content) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var answer datatypes.JSON answer, err = json.Marshal([]string{}) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } userquiz := &models.UserQuiz{ GUID: uuid.NewString(), CenterID: request.CenterID, UserQuizPaperID: request.UserQuizPaperID, No: request.No, QuizID: request.QuizID, QuestionType: request.QuestionType, Question: request.Question, Content: content, Answer: answer, UpdatedAt: time.Now(), CreatedAt: time.Now(), } result, err := controller.service.Create(userquiz) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, result) } // Update Quiz // // @Summary 사용자퀴즈 수정 // @Description 사용자퀴즈를 수정합니다. // @Tags 사용자퀴즈 // // @Accept json // @Produce json // // @Security Bearer // // @Param id path int64 true "Quiz ID" // @Param quizBody body models.UserQuizRequest true "Quiz Body" // // @Success 200 {object} models.UserQuizResponse // @Router /userquiz/{id} [put] func (controller *userQuizController) Update(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var request models.UserQuizRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } userquiz, err := controller.service.Find(id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var content datatypes.JSON content, err = json.Marshal(request.Content) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var answer datatypes.JSON answer, err = json.Marshal([]string{}) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } userquiz.CenterID = request.CenterID userquiz.UserQuizPaperID = request.UserQuizPaperID userquiz.No = request.No userquiz.QuestionType = request.QuestionType userquiz.Question = request.Question userquiz.Content = content userquiz.Answer = answer userquiz.Status = request.Status userquiz.Score = request.Score result, err := controller.service.Update(userquiz) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, result) } // Answer Quiz // // @Summary 사용자퀴즈 답변 // @Description 사용자퀴즈 답변을 제출합니다.. // @Tags 사용자퀴즈 // // @Accept json // @Produce json // // @Security Bearer // // @Param id path int64 true "Quiz ID" // @Param quizBody body models.AnswerQuizRequest true "Answer Body" // // @Router /userquiz/{id} [patch] func (controller *userQuizController) Answer(c *gin.Context) { id, err := strconv.ParseInt(c.Param("id"), 10, 64) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var request models.AnswerQuizRequest if err := c.ShouldBindJSON(&request); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } userquiz, err := controller.service.Find(id) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } user_id := c.GetInt64("sub") if user_id != userquiz.UserID { c.JSON(http.StatusBadRequest, gin.H{"error": "Wrong user"}) return } if userquiz.Status != "ready" { c.JSON(http.StatusBadRequest, gin.H{"error": "Answered"}) return } quiz, err := controller.quizService.Find(userquiz.QuizID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var userAnswer datatypes.JSON userAnswer, err = json.Marshal(request.Answer) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } isCorrect := cmp.Equal(quiz.Answer.String(), userAnswer.String()) var score float32 = 0.0 var correction string = "fail" if isCorrect { score = 1.0 correction = "success" } userquiz.Answer = userAnswer userquiz.Status = "done" userquiz.Result = correction userquiz.Score = score _, err = controller.service.Update(userquiz) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } _, err = controller.userquizpaperService.UpdateScore(userquiz.UserQuizPaperID) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // fmt.Println("userscore : ", result.UserScore) c.JSON(http.StatusOK, gin.H{"message": "success"}) }