2024-02-19 22:43:31 +09:00
|
|
|
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"
|
|
|
|
"gorm.io/datatypes"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PaperController interface {
|
|
|
|
List(*gin.Context)
|
|
|
|
Find(*gin.Context)
|
|
|
|
Start(*gin.Context)
|
|
|
|
Finish(*gin.Context)
|
|
|
|
|
|
|
|
QuizList(*gin.Context)
|
|
|
|
QuizFind(*gin.Context)
|
|
|
|
QuizAnswer(*gin.Context)
|
|
|
|
}
|
|
|
|
|
|
|
|
type paperController struct {
|
|
|
|
service services.PaperService
|
|
|
|
paperQuizService services.PaperQuizService
|
|
|
|
userService services.UserService
|
|
|
|
quizService services.QuizService
|
|
|
|
quizPaperService services.QuizPaperService
|
|
|
|
userQuizService services.UserQuizService
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPaperController(
|
|
|
|
service services.PaperService,
|
|
|
|
paperQuizService services.PaperQuizService,
|
|
|
|
quizService services.QuizService,
|
|
|
|
quizPaperService services.QuizPaperService,
|
|
|
|
userService services.UserService,
|
|
|
|
userQuizServie services.UserQuizService,
|
|
|
|
) PaperController {
|
|
|
|
return &paperController{
|
|
|
|
service: service,
|
|
|
|
paperQuizService: paperQuizService,
|
|
|
|
userService: userService,
|
|
|
|
quizService: quizService,
|
|
|
|
quizPaperService: quizPaperService,
|
|
|
|
userQuizService: userQuizServie,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Paper List
|
|
|
|
//
|
|
|
|
// @Summary 목록 가져오기
|
|
|
|
// @Description 목록을 가져옵니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param q query string false "검색어"
|
|
|
|
// @Param page query int false "페이지"
|
|
|
|
// @Param limit query int false "페이지 사이즈"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} models.PaperListResponse
|
|
|
|
// @Router /paper [get]
|
|
|
|
func (controller *paperController) List(c *gin.Context) {
|
|
|
|
q := c.DefaultQuery("q", "")
|
|
|
|
page, err := strconv.Atoi(c.DefaultQuery("page", "1"))
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
limit, err := strconv.Atoi(c.DefaultQuery("limit", "10"))
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
user_id := c.GetInt64("sub")
|
|
|
|
result, err := controller.service.List(user_id, q, page, limit)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
totalNumber, err := controller.service.Total(user_id, q)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
totalPage := int64(totalNumber/int64(limit) + 1)
|
|
|
|
|
|
|
|
response := models.PaperListResponse{
|
|
|
|
Data: *result,
|
|
|
|
Total: totalNumber,
|
|
|
|
Page: page,
|
|
|
|
TotalPage: totalPage,
|
|
|
|
PageSize: limit,
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, response)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get paper
|
|
|
|
//
|
|
|
|
// @Summary 페이퍼 정보 가져오기
|
|
|
|
// @Description ID로 페이퍼 정보를 가져옵니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path int64 true "Paper ID"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} models.PaperResponse
|
|
|
|
// @Router /paper/{paper_id} [get]
|
|
|
|
func (controller *paperController) Find(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("paper_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := controller.service.Find(paper_id)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Start Paper
|
|
|
|
//
|
|
|
|
// @Summary 퀴즈 시작
|
|
|
|
// @Description 퀴즈 시작합니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path int64 true "Paper ID"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} models.Paper
|
|
|
|
// @Router /paper/{paper_id}/start [patch]
|
|
|
|
func (controller *paperController) Start(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("paper_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
paper, err := controller.service.Get(paper_id)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if paper.Status != "ready" {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "퀴즈를 시작할 수 없습니다."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now()
|
|
|
|
paper.Status = "start"
|
|
|
|
paper.StartAt = &now
|
|
|
|
|
|
|
|
result, err := controller.service.Update(paper)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Finish Paper
|
|
|
|
//
|
|
|
|
// @Summary 퀴즈 종료
|
|
|
|
// @Description 퀴즈 종료합니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path int64 true "Paper ID"
|
|
|
|
//
|
|
|
|
// @Success 200 {object} models.Paper
|
|
|
|
// @Router /paper/{paper_id}/finish [patch]
|
|
|
|
func (controller *paperController) Finish(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("paper_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
paper, err := controller.service.Get(paper_id)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if paper.Status != "start" {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "퀴즈를 종료할 수 없습니다."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now()
|
2024-02-19 23:17:41 +09:00
|
|
|
paper.Status = "done"
|
2024-02-19 22:43:31 +09:00
|
|
|
paper.DoneAt = &now
|
|
|
|
|
|
|
|
result, err := controller.service.Update(paper)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Quiz List
|
|
|
|
//
|
|
|
|
// @Summary 퀴즈페이퍼 퀴즈 목록 가져오기
|
|
|
|
// @Description 퀴즈페이퍼 퀴즈 목록을 가져옵니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path int64 true "퀴즈페이퍼 ID"
|
|
|
|
// @Param page query int false "페이지"
|
|
|
|
// @Param limit query int false "페이지 사이즈"
|
|
|
|
//
|
2024-02-19 22:58:00 +09:00
|
|
|
// @Success 200 {object} models.PaperQuizListResponse
|
2024-02-19 22:43:31 +09:00
|
|
|
// @Router /paper/{paper_id}/quiz [get]
|
|
|
|
func (controller *paperController) QuizList(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("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.paperQuizService.List(paper_id, page, limit)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
totalNumber, err := controller.paperQuizService.Total(paper_id)
|
|
|
|
if err != nil {
|
|
|
|
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 Quiz
|
|
|
|
//
|
|
|
|
// @Summary 퀴즈페이퍼 퀴즈 가져오기
|
|
|
|
// @Description ID로 퀴즈를 가져옵니다.
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path string true "Paper ID"
|
|
|
|
// @Param quiz_id path string true "사용자퀴즈 ID"
|
|
|
|
//
|
2024-02-19 22:58:00 +09:00
|
|
|
// @Success 200 {object} models.PaperQuizResponse
|
2024-02-19 22:43:31 +09:00
|
|
|
// @Router /paper/{paper_id}/quiz/{quiz_id} [get]
|
|
|
|
func (controller *paperController) QuizFind(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("paper_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
quiz_id, err := strconv.ParseInt(c.Param("quiz_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := controller.paperQuizService.Find(quiz_id)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if paper_id != result.UserQuizPaperID {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "퀴즈시트와 퀴즈가 일치하지 않습니다."})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, result)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Answer Quiz
|
|
|
|
//
|
|
|
|
// @Summary 퀴즈 답변
|
|
|
|
// @Description 퀴즈 답변을 제출합니다..
|
|
|
|
// @Tags 페이퍼
|
|
|
|
//
|
|
|
|
// @Accept json
|
|
|
|
// @Produce json
|
|
|
|
//
|
|
|
|
// @Security Bearer
|
|
|
|
//
|
|
|
|
// @Param paper_id path int64 true "Paper ID"
|
|
|
|
// @Param quiz_id path int64 true "Quiz ID"
|
|
|
|
// @Param quizBody body models.AnswerQuizRequest true "Answer Body"
|
|
|
|
//
|
|
|
|
// @Router /paper/{paper_id}/quiz/{quiz_id}/answer [patch]
|
|
|
|
func (controller *paperController) QuizAnswer(c *gin.Context) {
|
|
|
|
paper_id, err := strconv.ParseInt(c.Param("paper_id"), 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
id, err := strconv.ParseInt(c.Param("quiz_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.userQuizService.Find(id)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if paper_id != userquiz.UserQuizPaperID {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"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
|
2024-02-19 23:17:41 +09:00
|
|
|
var correction string = "fail"
|
2024-02-19 22:43:31 +09:00
|
|
|
if isCorrect {
|
|
|
|
score = 1.0
|
2024-02-19 23:17:41 +09:00
|
|
|
correction = "success"
|
2024-02-19 22:43:31 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
userquiz.Answer = userAnswer
|
2024-02-19 23:17:41 +09:00
|
|
|
userquiz.Status = "done"
|
2024-02-19 22:43:31 +09:00
|
|
|
userquiz.Result = correction
|
|
|
|
userquiz.Score = score
|
|
|
|
|
|
|
|
_, err = controller.userQuizService.Update(userquiz)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err = controller.service.UpdateScore(userquiz.UserQuizPaperID)
|
|
|
|
if err != nil {
|
|
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
c.JSON(http.StatusOK, gin.H{"message": "success"})
|
|
|
|
}
|