learnsteam-quiz-api/internal/controllers/exam.go

307 lines
7.1 KiB
Go

package controllers
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"
"learnsteam/learsteam-quiz-api/internal/models"
"learnsteam/learsteam-quiz-api/internal/services"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
)
type ExamController interface {
List(*gin.Context)
Find(*gin.Context)
Create(*gin.Context)
Update(*gin.Context)
Patch(*gin.Context)
}
type examController struct {
service services.ExamService
userService services.UserService
programService services.ProgramService
}
func NewExamController(service services.ExamService, userService services.UserService, programService services.ProgramService) ExamController {
return &examController{
service: service,
userService: userService,
programService: programService,
}
}
// Exam List
//
// @Summary 응시 목록 가져오기
// @Description 응시 목록을 가져옵니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param q query string false "검색어"
// @Param page query int false "페이지"
// @Param limit query int false "페이지 사이즈"
//
// @Success 200 {object} models.ExamListResponse
// @Router /exam [get]
func (controller *examController) List(c *gin.Context) {
q := c.DefaultQuery("q", "")
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(q, page, limit)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
totalNumber, err := controller.service.Total(q)
if err != nil {
fmt.Println("error : list")
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
totalPage := int64(totalNumber/int64(limit) + 1)
response := models.ExamListResponse{
Data: *result,
Total: totalNumber,
Page: page,
TotalPage: totalPage,
PageSize: limit,
}
c.JSON(http.StatusOK, response)
}
// Get exam
//
// @Summary 응시 정보 가져오기
// @Description ID로 응시 정보를 가져옵니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param id path string true "응시 ID"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam/{id} [get]
func (controller *examController) Find(c *gin.Context) {
id := c.Param("id")
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 Exam
//
// @Summary 응시 매칭 생성
// @Description 응시 매칭을 만듭니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examBody body models.ExamRequest true "Exam Body"
//
// @Success 200 {object} []models.Exam
// @Router /exam [post]
func (controller *examController) Create(c *gin.Context) {
var request models.ExamRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("users", request.Users)
program, err := controller.programService.Find(request.ProgramID)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var users []string
err = json.Unmarshal(request.Users, &users)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var exams []*models.Exam
for _, user_id := range users {
user, err := controller.userService.Find(user_id)
if err != nil {
continue
}
exam := &models.Exam{
ID: uuid.NewString(),
ProgramID: program.ID,
UserID: user_id,
Subject: program.Subject,
Program: program.Course,
Name: user.Name,
Score: 0,
Total: 5,
Status: "ready",
}
result, err := controller.service.Create(exam)
if err != nil {
continue
}
exams = append(exams, result)
}
c.JSON(http.StatusOK, exams)
}
// Update Exam
//
// @Summary 응시 수정
// @Description 응시를 수정합니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examUpdateBody body models.ExamUpdateRequest true "Exam Update Body"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam [put]
func (controller *examController) Update(c *gin.Context) {
id := c.Param("id")
var request models.ExamUpdateRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("request", request)
exam, err := controller.service.Find(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
exam.ProgramID = request.ProgramID
exam.UserID = request.UserID
exam.Subject = request.Subject
exam.Program = request.Program
exam.Name = request.Name
exam.Status = request.Status
exam.Score = request.Score
exam.Total = request.Total
if request.StartAt != "" {
fmt.Println("request.StartAt", request.StartAt)
start_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.StartAt)
if err == nil {
exam.StartAt = &start_at
}
fmt.Println("start_at", start_at)
}
if request.EndAt != "" {
fmt.Println("request.EndAt", request.EndAt)
end_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.EndAt)
if err == nil {
exam.EndAt = &end_at
}
fmt.Println("end_at", end_at)
}
fmt.Println("exam", exam)
result, err := controller.service.Update(exam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("result", result)
c.JSON(http.StatusOK, result)
}
// Patch Exam
//
// @Summary 응시 정보 변경
// @Description 응시 정보를 변경합니다.
// @Tags Exam
//
// @Accept json
// @Produce json
//
// @Param examPatchBody body models.ExamPatchRequest true "Exam Patch Body (변경할 필드만 입력)"
//
// @Success 200 {object} models.ExamResponse
// @Router /exam [patch]
func (controller *examController) Patch(c *gin.Context) {
id := c.Param("id")
var request models.ExamPatchRequest
if err := c.ShouldBindJSON(&request); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("request", request)
exam, err := controller.service.Find(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
if request.Status != "" {
exam.Status = request.Status
}
if request.StartAt != "" {
fmt.Println("request.StartAt", request.StartAt)
start_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.StartAt)
if err == nil {
exam.StartAt = &start_at
}
fmt.Println("start_at", start_at)
}
if request.EndAt != "" {
fmt.Println("request.EndAt", request.EndAt)
end_at, err := time.Parse("2006-01-02T15:04:05-07:00", request.EndAt)
if err == nil {
exam.EndAt = &end_at
}
fmt.Println("end_at", end_at)
}
fmt.Println("exam", exam)
result, err := controller.service.Update(exam)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
fmt.Println("result", result)
c.JSON(http.StatusOK, result)
}