퀴즈 풀기/점수

This commit is contained in:
2024-02-19 22:43:31 +09:00
parent 41e1ed5c58
commit 05292be591
24 changed files with 2425 additions and 39 deletions

View File

@ -0,0 +1,426 @@
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()
paper.Status = "finish"
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 "페이지 사이즈"
//
// @Success 200 {object} models.UserQuizListResponse
// @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"
//
// @Success 200 {object} models.UserQuizResponse
// @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
var correction string = "wrong"
if isCorrect {
score = 1.0
correction = "correct"
}
userquiz.Answer = userAnswer
userquiz.Status = "answer"
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"})
}

View File

@ -11,6 +11,7 @@ import (
"learnsteam/cslms-api/internal/services"
"github.com/gin-gonic/gin"
"github.com/google/go-cmp/cmp"
"github.com/google/uuid"
"gorm.io/datatypes"
)
@ -20,15 +21,20 @@ type UserQuizController interface {
Find(*gin.Context)
Create(*gin.Context)
Update(*gin.Context)
Answer(*gin.Context)
}
type userQuizController struct {
service services.UserQuizService
service services.UserQuizService
quizService services.QuizService
userquizpaperService services.UserQuizPaperService
}
func NewUserQuizController(service services.UserQuizService) UserQuizController {
func NewUserQuizController(service services.UserQuizService, quizService services.QuizService, userquizpaperService services.UserQuizPaperService) UserQuizController {
return &userQuizController{
service: service,
service: service,
quizService: quizService,
userquizpaperService: userquizpaperService,
}
}
@ -154,7 +160,7 @@ func (controller *userQuizController) Create(c *gin.Context) {
return
}
quiz := &models.UserQuiz{
userquiz := &models.UserQuiz{
GUID: uuid.NewString(),
CenterID: request.CenterID,
UserQuizPaperID: request.UserQuizPaperID,
@ -168,7 +174,7 @@ func (controller *userQuizController) Create(c *gin.Context) {
CreatedAt: time.Now(),
}
result, err := controller.service.Create(quiz)
result, err := controller.service.Create(userquiz)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
@ -212,18 +218,6 @@ func (controller *userQuizController) Update(c *gin.Context) {
return
}
// CenterID int64 `json:"center_id" example:"1000001"`
// UserQuizPaperID int64 `json:"quiz_paper_id" example:"1000001"`
// UserID int64 `json:"user_id" example:"1000001"`
// No int `json:"vol_no" example:"1"`
// QuestionType string `json:"question_type" example:"choice"`
// Question string `json:"question" example:"질문입니다."`
// Content datatypes.JSON `json:"content"`
// Answer datatypes.JSON `json:"answer"`
// Status string `json:"status" example:"waiting"`
// Result string `json:"result" example:"success"`
// Score float32 `json:"score" example:"10"`
var content datatypes.JSON
content, err = json.Marshal(request.Content)
if err != nil {
@ -256,3 +250,91 @@ func (controller *userQuizController) Update(c *gin.Context) {
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 = "wrong"
if isCorrect {
score = 1.0
correction = "correct"
}
userquiz.Answer = userAnswer
userquiz.Status = "answer"
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"})
}

59
internal/models/paper.go Normal file
View File

@ -0,0 +1,59 @@
package models
import (
"time"
)
type Paper struct {
ID int64 `json:"id" db:"id" example:"1000015" gorm:"column:id;primary_key;"`
GUID string `json:"guid_id" db:"guid_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4" gorm:"column:guid_id;size:255;uniqueIndex"`
CenterID int64 `json:"center_id" db:"center_id" example:"1000015" gorm:"column:center_id;index;"`
QuizPaperID int64 `json:"quiz_paper_id" db:"quiz_paper_id" example:"1000001" gorm:"column:quiz_paper_id;index;"`
UserID int64 `json:"user_id" db:"user_id" example:"1000002" gorm:"column:user_id;index;"`
UserScore float32 `json:"user_score" db:"user_score" example:"5" gorm:"column:user_score;"`
TotalScore float32 `json:"total_score" db:"total_score" example:"100" gorm:"column:total_score;"`
Status string `json:"status" example:"wating" gorm:"column:status;size:10;index;"`
StartAt *time.Time `json:"start_at" gorm:"column:start_at;index;"`
DoneAt *time.Time `json:"done_at" gorm:"column:done_at;index;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
// 테이블이름 정의
func (Paper) TableName() string {
return "UserQuizPapers"
}
type PaperResponse struct {
ID int64 `json:"id" db:"id" example:"1000015"`
GUID string `json:"guid_id" db:"guid_id" example:"7f9329f5-2e36-4638-92d2-73064b7291a4"`
CenterID int64 `json:"center_id" db:"center_id" example:"1000015"`
QuizPaperID int64 `json:"quiz_paper_id" db:"quiz_paper_id" example:"1000001"`
UserID int64 `json:"user_id" db:"user_id" example:"1000002"`
FirstName string `json:"first_name" db:"first_name" example:"길순"`
LastName string `json:"last_name" db:"last_name" example:"홍"`
UserScore float32 `json:"user_score" db:"user_score" example:"5"`
TotalScore float32 `json:"total_score" db:"total_score" example:"100"`
Status string `json:"status" example:"wating"`
Category string `json:"category" example:"파이썬기본"`
Title string `json:"title" example:"출력 Print"`
StartAt *time.Time `json:"start_at"`
DoneAt *time.Time `json:"done_at"`
CreatedAt *time.Time `json:"created_at"`
}
type PaperPatchRequest struct {
UserScore float32 `json:"user_score" example:"4"`
TotalScore float32 `json:"total_score" example:"80"`
Status string `json:"status" example:"ready"`
StartAt string `json:"start_at,omitempty" example:"2023-11-10T13:10:00+09:00"`
DoneAt string `json:"done_at,omitempty" example:"2023-11-10T13:25:00+09:00"`
}
type PaperListResponse struct {
Data []PaperResponse `json:"data"`
Total int64 `json:"total" example:"999"`
Page int `json:"page" example:"1"`
TotalPage int64 `json:"totalPage" example:"99"`
PageSize int `json:"pageSize" example:"10"`
}

View File

@ -0,0 +1,54 @@
package models
import (
"time"
"gorm.io/datatypes"
)
type PaperQuiz struct {
ID int64 `json:"id" db:"id" example:"1000001" gorm:"column:id;primary_key;"`
GUID string `json:"guid_id" db:"guid_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6" gorm:"column:guid_id;size:255;index;"`
CenterID int64 `json:"center_id" db:"center_id" example:"100001" gorm:"column:center_id;index;"`
UserQuizPaperID int64 `json:"user_quiz_paper_id" db:"user_quiz_paper_id" example:"1000001" gorm:"column:user_quiz_paper_id;index;"`
UserID int64 `json:"user_id" db:"user_id" example:"1000001" gorm:"column:user_id;index;"`
QuizID int64 `json:"quiz_id" db:"quiz_id" example:"1000001" gorm:"column:quiz_id;index;"`
No int `json:"vol_no" db:"vol_no" example:"5" gorm:"column:vol_no;index;"`
QuestionType string `json:"question_type" db:"question_type" example:"choice" gorm:"column:question_type;size:10;index;"`
Question string `json:"question" db:"question" example:"퀴즈 질문입니다." gorm:"column:question;size:512;"`
Content datatypes.JSON `json:"content" db:"content" gorm:"column:content;"`
Status string `json:"status" db:"status" example:"waiting" gorm:"column:status;size:10;index;"`
Result string `json:"result" db:"result" example:"success" gorm:"column:result;size:10;index;"`
Score float32 `json:"score" db:"score" example:"10" gorm:"column:score;"`
UpdatedAt time.Time `json:"-" gorm:"column:updated_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;index;->:false"`
CreatedAt time.Time `json:"-" gorm:"column:created_at;type:DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP;index;->:false;<-:create"`
}
// 테이블이름 정의
func (PaperQuiz) TableName() string {
return "UserQuizs"
}
type PaperQuizResponse struct {
ID int64 `json:"id" example:"1000001"`
GUID string `json:"guid_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6"`
CenterD string `json:"center_id" example:"2036023a-fb56-4b6c-b3bb-c787c681ada6"`
UserQuizPaperID int64 `json:"user_quiz_paper_id" example:"1000001"`
UserID int64 `json:"user_id" example:"1000001"`
QuizID int64 `json:"quiz_id" example:"1000001"`
No int `json:"vol_no" example:"5"`
QuestionType string `json:"question_type" example:"check"`
Question string `json:"question" example:"퀴즈 질문입니다."`
Content QuizContent `json:"content"`
Status string `json:"status" example:"waiting"`
Result string `json:"result" example:"success"`
Score float32 `json:"score" example:"10"`
}
type PaperQuizListResponse struct {
Data []UserQuizResponse `json:"data"`
Total int64 `json:"total" example:"5"`
Page int `json:"page" example:"1"`
TotalPage int64 `json:"totalPage" example:"1"`
PageSize int `json:"pageSize" example:"10"`
}

View File

@ -69,3 +69,7 @@ type UserQuizListResponse struct {
TotalPage int64 `json:"totalPage" example:"1"`
PageSize int `json:"pageSize" example:"10"`
}
type AnswerQuizRequest struct {
Answer []string `json:"answer" example:"option1,option4"`
}

View File

@ -0,0 +1,101 @@
package repositories
import (
"learnsteam/cslms-api/internal/models"
"gorm.io/gorm"
)
type paperRepository struct {
DB *gorm.DB
}
func NewPaperRepository(db *gorm.DB) PaperRepository {
return &paperRepository{
DB: db,
}
}
type PaperRepository interface {
List(int64, string, int, int) (*[]models.PaperResponse, error)
Total(int64, string) (int64, error)
Find(int64) (*models.PaperResponse, error)
Get(int64) (*models.Paper, error)
Update(*models.Paper) (*models.Paper, error)
}
func (r *paperRepository) List(user_id int64, q string, page int, limit int) (*[]models.PaperResponse, error) {
var rows *[]models.PaperResponse
var err error
offset := limit * (page - 1)
if q != "" {
err = r.DB.Offset(offset).Limit(limit).Order("UserQuizPapers.created_at DESC").
Table("UserQuizPapers").
Select("UserQuizPapers.*", "Users.first_name", "Users.last_name", "QuizPapers.title", "QuizPapers.category").
Joins("LEFT JOIN Users ON Users.id = UserQuizPapers.user_id").
Joins("LEFT JOIN QuizPapers ON QuizPapers.id = UserQuizPapers.quiz_paper_id").
Where("QuizPapers.title LIKE ? OR QuizPapers.category LIKE ? OR CONCAT(first_name, last_name) LIKE ?", "%"+q+"%", "%"+q+"%", "%"+q+"%").
Where("UserQuizPapers.user_id = ?", user_id).
Find(&rows).Error
} else {
err = r.DB.Offset(offset).Limit(limit).Order("UserQuizPapers.created_at DESC").
Table("UserQuizPapers").
Select("UserQuizPapers.*", "Users.first_name", "Users.last_name", "QuizPapers.title", "QuizPapers.category").
Joins("LEFT JOIN Users ON Users.id = UserQuizPapers.user_id").
Joins("LEFT JOIN QuizPapers ON QuizPapers.id = UserQuizPapers.quiz_paper_id").
Where("UserQuizPapers.user_id = ?", user_id).
Find(&rows).Error
}
return rows, err
}
func (r *paperRepository) Total(user_id int64, q string) (int64, error) {
var total int64
var err error
if q != "" {
err = r.DB.Model(&models.Paper{}).
Joins("LEFT JOIN Users ON Users.id = UserQuizPapers.user_id").
Joins("LEFT JOIN QuizPapers ON QuizPapers.id = UserQuizPapers.quiz_paper_id").
Where("QuizPapers.title LIKE ? OR QuizPapers.category LIKE ? OR CONCAT(first_name, last_name) LIKE ?", "%"+q+"%", "%"+q+"%", "%"+q+"%").
Where("UserQuizPapers.user_id = ?", user_id).
Count(&total).
Error
} else {
err = r.DB.Model(&models.Paper{}).
Where("user_id = ?", user_id).
Count(&total).
Error
}
return total, err
}
func (r *paperRepository) Find(id int64) (*models.PaperResponse, error) {
var row *models.PaperResponse
err := r.DB.
Table("UserQuizPapers").
Select("UserQuizPapers.*", "Users.first_name", "Users.last_name", "QuizPapers.title", "QuizPapers.category").
Joins("LEFT JOIN Users ON Users.id = UserQuizPapers.user_id").
Joins("LEFT JOIN QuizPapers ON QuizPapers.id = UserQuizPapers.quiz_paper_id").
Where("UserQuizPapers.id = ?", id).First(&row).Error
return row, err
}
func (r *paperRepository) Get(id int64) (*models.Paper, error) {
var row *models.Paper
if err := r.DB.Where("id=?", id).First(&row).Error; err != nil {
return nil, err
}
return row, nil
}
func (r *paperRepository) Update(paper *models.Paper) (*models.Paper, error) {
var row *models.Paper
if err := r.DB.Where("id=?", paper.ID).First(&row).Error; err != nil {
return nil, err
}
err := r.DB.Model(&row).Select("*").Updates(&paper).Error
return row, err
}

View File

@ -0,0 +1,89 @@
package repositories
import (
"learnsteam/cslms-api/internal/models"
"gorm.io/gorm"
)
type paperQuizRepository struct {
DB *gorm.DB
}
func NewPaperQuizRepository(db *gorm.DB) PaperQuizRepository {
return &paperQuizRepository{
DB: db,
}
}
type PaperQuizRepository interface {
List(int64, int, int) (*[]models.PaperQuiz, error)
Total(int64) (int64, error)
Find(int64) (*models.PaperQuiz, error)
Update(*models.PaperQuiz) (*models.PaperQuiz, error)
Delete(int64) error
SumScore(int64) (float32, error)
}
func (r *paperQuizRepository) List(paper_id int64, page int, limit int) (*[]models.PaperQuiz, error) {
var rows *[]models.PaperQuiz
var err error
offset := limit * (page - 1)
if paper_id > 0 {
err = r.DB.Offset(offset).Limit(limit).Order("vol_no ASC").Where("user_quiz_paper_id = ?", paper_id).Find(&rows).Error
} else {
err = r.DB.Offset(offset).Limit(limit).Find(&rows).Error
}
return rows, err
}
func (r *paperQuizRepository) Total(paper_id int64) (int64, error) {
var total int64
var err error
if paper_id > 0 {
err = r.DB.Model(&models.PaperQuiz{}).Where("user_quiz_paper_id = ?", paper_id).Count(&total).Error
} else {
err = r.DB.Model(&models.PaperQuiz{}).Count(&total).Error
}
return total, err
}
func (r *paperQuizRepository) Find(id int64) (*models.PaperQuiz, error) {
var row *models.PaperQuiz
err := r.DB.Where("id = ?", id).First(&row).Error
return row, err
}
func (r *paperQuizRepository) Update(quiz *models.PaperQuiz) (*models.PaperQuiz, error) {
var row *models.PaperQuiz
if err := r.DB.Where("id=?", quiz.ID).First(&row).Error; err != nil {
return nil, err
}
err := r.DB.Model(&row).Select("*").Updates(&quiz).Error
return row, err
}
func (r *paperQuizRepository) Delete(id int64) error {
var row *models.PaperQuiz
if err := r.DB.Where("id=?", id).First(&row).Error; err != nil {
return err
}
err := r.DB.Delete(&row).Error
return err
}
func (r *paperQuizRepository) SumScore(paper_id int64) (float32, error) {
var result struct {
Score float32
}
if err := r.DB.Model(&models.PaperQuiz{}).Select("SUM(score) AS score").
Where("user_quiz_paper_id = ?", paper_id).
Scan(&result).Error; err != nil {
return 0, err
}
return result.Score, nil
}

View File

@ -26,6 +26,7 @@ type UserQuizRepository interface {
Insert([]models.UserQuiz) ([]models.UserQuiz, error)
Update(*models.UserQuiz) (*models.UserQuiz, error)
Delete(int64) error
SumScore(int64) (float32, error)
}
func (r *userQuizRepository) List(user_quiz_paper_id int64, page int, limit int) (*[]models.UserQuiz, error) {
@ -86,3 +87,16 @@ func (r *userQuizRepository) Delete(id int64) error {
err := r.DB.Delete(&row).Error
return err
}
func (r *userQuizRepository) SumScore(userquizpaper_id int64) (float32, error) {
var result struct {
Score float32
}
if err := r.DB.Model(&models.UserQuiz{}).Select("SUM(score) AS score").
Where("user_quiz_paper_id = ?", userquizpaper_id).
Scan(&result).Error; err != nil {
return 0, err
}
return result.Score, nil
}

89
internal/routers/paper.go Normal file
View File

@ -0,0 +1,89 @@
package routers
import (
"learnsteam/cslms-api/internal/controllers"
"learnsteam/cslms-api/internal/middleware"
"learnsteam/cslms-api/internal/repositories"
"learnsteam/cslms-api/internal/services"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
func InitPaperRouter(db *gorm.DB, router *gin.Engine) {
r := NewPaperRouter(db, router)
r.SetPaperRouter()
}
type PaperRouter interface {
SetRouter(db *gorm.DB, router *gin.Engine)
}
type paperRouter struct {
db *gorm.DB
repository repositories.PaperRepository
paperQuizRepository repositories.PaperQuizRepository
quizRepository repositories.QuizRepository
quizPaperRepository repositories.QuizPaperRepository
userRepository repositories.UserRepository
userQuizRepository repositories.UserQuizRepository
service services.PaperService
paperQuizService services.PaperQuizService
quizService services.QuizService
quizPaperService services.QuizPaperService
userService services.UserService
userQuizService services.UserQuizService
controller controllers.PaperController
router *gin.Engine
}
func NewPaperRouter(db *gorm.DB, router *gin.Engine) *paperRouter {
repository := repositories.NewPaperRepository(db)
paperQuizRepository := repositories.NewPaperQuizRepository(db)
quizRepository := repositories.NewQuizRepository(db)
quizPaperRepository := repositories.NewQuizPaperRepository(db)
tokenRepository := repositories.NewTokenRepository(db)
userRepository := repositories.NewUserRepository(db)
userQuizRepository := repositories.NewUserQuizRepository(db)
service := services.NewPaperService(repository, paperQuizRepository)
paperQuizService := services.NewPaperQuizService(paperQuizRepository)
quizService := services.NewQuizService(quizRepository)
quizPaperService := services.NewQuizPaperService(quizPaperRepository)
userService := services.NewUserService(userRepository, tokenRepository)
userQuizService := services.NewUserQuizService(userQuizRepository, quizRepository)
controller := controllers.NewPaperController(service, paperQuizService, quizService, quizPaperService, userService, userQuizService)
return &paperRouter{
db: db,
repository: repository,
quizRepository: quizRepository,
quizPaperRepository: quizPaperRepository,
userRepository: userRepository,
userQuizRepository: userQuizRepository,
service: service,
paperQuizService: paperQuizService,
quizService: quizService,
quizPaperService: quizPaperService,
userService: userService,
userQuizService: userQuizService,
controller: controller,
router: router,
}
}
func (r *paperRouter) SetPaperRouter() {
group := r.router.Group("/paper")
group.GET("", middleware.Auth("member"), r.controller.List)
group.GET("/:paper_id", middleware.Auth("member"), r.controller.Find)
group.PATCH("/:paper_id/start", middleware.Auth("member"), r.controller.Start)
group.PATCH("/:paper_id/finish", middleware.Auth("member"), r.controller.Finish)
group.GET("/:paper_id/quiz", middleware.Auth("member"), r.controller.QuizList)
group.GET("/:paper_id/quiz/:quiz_id", middleware.Auth("member"), r.controller.QuizFind)
group.PATCH("/:paper_id/quiz/:quiz_id/answer", middleware.Auth("member"), r.controller.QuizAnswer)
}

View File

@ -25,6 +25,7 @@ func Init() {
InitAuthRouter(maindb, Router)
InitCenterRouter(maindb, Router)
InitPaperRouter(maindb, Router)
InitQuizPaperRouter(maindb, Router)
InitQuizRouter(maindb, Router)
InitTokenRouter(maindb, Router)

View File

@ -20,27 +20,42 @@ type UserQuizRouter interface {
}
type userQuizRouter struct {
db *gorm.DB
repository repositories.UserQuizRepository
quizRepository repositories.QuizRepository
service services.UserQuizService
controller controllers.UserQuizController
router *gin.Engine
db *gorm.DB
repository repositories.UserQuizRepository
quizRepository repositories.QuizRepository
userquizRepository repositories.UserQuizRepository
userquizpaperRepository repositories.UserQuizPaperRepository
service services.UserQuizService
quizService services.QuizService
userquizService services.UserQuizService
userquizpaperService services.UserQuizPaperService
controller controllers.UserQuizController
router *gin.Engine
}
func NewUserQuizRouter(db *gorm.DB, router *gin.Engine) *userQuizRouter {
repository := repositories.NewUserQuizRepository(db)
quizRepostory := repositories.NewQuizRepository(db)
userquizRepository := repositories.NewUserQuizRepository(db)
userquizpaperRepository := repositories.NewUserQuizPaperRepository(db)
service := services.NewUserQuizService(repository, quizRepostory)
controller := controllers.NewUserQuizController(service)
quizService := services.NewQuizService(quizRepostory)
userquizService := services.NewUserQuizService(userquizRepository, quizRepostory)
userquizpaperService := services.NewUserQuizPaperService(userquizpaperRepository, userquizRepository)
controller := controllers.NewUserQuizController(service, quizService, userquizpaperService)
return &userQuizRouter{
db: db,
repository: repository,
quizRepository: quizRepostory,
service: service,
controller: controller,
router: router,
db: db,
repository: repository,
quizRepository: quizRepostory,
userquizpaperRepository: userquizpaperRepository,
userquizRepository: userquizRepository,
service: service,
quizService: quizService,
userquizpaperService: userquizpaperService,
userquizService: userquizService,
controller: controller,
router: router,
}
}
@ -50,4 +65,5 @@ func (r *userQuizRouter) SetUserQuizRouter() {
group.GET("/:id", middleware.Auth("admin"), r.controller.Find)
group.POST("", middleware.Auth("admin"), r.controller.Create)
group.PUT("/:id", middleware.Auth("admin"), r.controller.Update)
group.PATCH("/:id", middleware.Auth("member"), r.controller.Answer)
}

View File

@ -42,7 +42,7 @@ func NewUserQuizPaperRouter(db *gorm.DB, router *gin.Engine) *userQuizPaperRoute
userRepository := repositories.NewUserRepository(db)
userQuizRepository := repositories.NewUserQuizRepository(db)
service := services.NewUserQuizPaperService(repository)
service := services.NewUserQuizPaperService(repository, userQuizRepository)
quizService := services.NewQuizService(quizRepository)
quizPaperService := services.NewQuizPaperService(quizPaperRepository)
userService := services.NewUserService(userRepository, tokenRepository)

View File

@ -0,0 +1,66 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type paperService struct {
repository repositories.PaperRepository
paperQuizRepository repositories.PaperQuizRepository
}
type PaperService interface {
List(int64, string, int, int) (*[]models.PaperResponse, error)
Total(int64, string) (int64, error)
Find(int64) (*models.PaperResponse, error)
Get(int64) (*models.Paper, error)
Update(*models.Paper) (*models.Paper, error)
UpdateScore(int64) (*models.Paper, error)
}
func NewPaperService(repository repositories.PaperRepository, paperQuizRepository repositories.PaperQuizRepository) PaperService {
return &paperService{
repository: repository,
paperQuizRepository: paperQuizRepository,
}
}
func (s *paperService) List(user_id int64, q string, page int, limit int) (*[]models.PaperResponse, error) {
return s.repository.List(user_id, q, page, limit)
}
func (s *paperService) Total(user_id int64, q string) (int64, error) {
return s.repository.Total(user_id, q)
}
func (s *paperService) Find(id int64) (*models.PaperResponse, error) {
return s.repository.Find(id)
}
func (s *paperService) Get(id int64) (*models.Paper, error) {
return s.repository.Get(id)
}
func (s *paperService) Update(paper *models.Paper) (*models.Paper, error) {
result, err := s.repository.Update(paper)
return result, err
}
func (s *paperService) UpdateScore(userquizpaper_id int64) (*models.Paper, error) {
score, err := s.paperQuizRepository.SumScore(userquizpaper_id)
if err != nil {
return nil, err
}
userquizpaper, err := s.repository.Get(userquizpaper_id)
if err != nil {
return nil, err
}
userquizpaper.UserScore = score
return s.repository.Update(userquizpaper)
}

View File

@ -0,0 +1,43 @@
package services
import (
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
)
type paperQuizService struct {
repository repositories.PaperQuizRepository
quizRepository repositories.QuizRepository
}
type PaperQuizService interface {
List(int64, int, int) (*[]models.PaperQuiz, error)
Total(int64) (int64, error)
Find(int64) (*models.PaperQuiz, error)
Update(*models.PaperQuiz) (*models.PaperQuiz, error)
}
func NewPaperQuizService(repository repositories.PaperQuizRepository) PaperQuizService {
return &paperQuizService{
repository: repository,
}
}
func (s *paperQuizService) List(user_quiz_paper_id int64, page int, limit int) (*[]models.PaperQuiz, error) {
return s.repository.List(user_quiz_paper_id, page, limit)
}
func (s *paperQuizService) Total(user_quiz_paper_id int64) (int64, error) {
return s.repository.Total(user_quiz_paper_id)
}
func (s *paperQuizService) Find(id int64) (*models.PaperQuiz, error) {
return s.repository.Find(id)
}
func (s *paperQuizService) Update(quiz *models.PaperQuiz) (*models.PaperQuiz, error) {
result, err := s.repository.Update(quiz)
return result, err
}

View File

@ -84,6 +84,7 @@ func (s *userQuizService) Generate(quiz_paper_id int64, userQuizPaper *models.Us
QuestionType: quiz.QuestionType,
Question: quiz.Question,
Content: quiz.Content,
Status: "ready",
}
fmt.Println(userQuiz.Content)

View File

@ -1,6 +1,7 @@
package services
import (
"fmt"
"learnsteam/cslms-api/internal/models"
"learnsteam/cslms-api/internal/repositories"
@ -8,7 +9,8 @@ import (
)
type userQuizPaperService struct {
repository repositories.UserQuizPaperRepository
repository repositories.UserQuizPaperRepository
userquizRepository repositories.UserQuizRepository
}
type UserQuizPaperService interface {
@ -22,11 +24,13 @@ type UserQuizPaperService interface {
Update(*models.UserQuizPaper) (*models.UserQuizPaper, error)
Delete(string) error
Generate([]int64, *models.QuizPaper) []models.UserQuizPaper
UpdateScore(int64) (*models.UserQuizPaper, error)
}
func NewUserQuizPaperService(repository repositories.UserQuizPaperRepository) UserQuizPaperService {
func NewUserQuizPaperService(repository repositories.UserQuizPaperRepository, userquizRepository repositories.UserQuizRepository) UserQuizPaperService {
return &userQuizPaperService{
repository: repository,
repository: repository,
userquizRepository: userquizRepository,
}
}
@ -79,6 +83,7 @@ func (s *userQuizPaperService) Generate(users []int64, quizPaper *models.QuizPap
CenterID: quizPaper.CenterID,
UserID: user_id,
QuizPaperID: quizPaper.ID,
Status: "ready",
}
userQuizPapers = append(userQuizPapers, userQuizPaper)
@ -86,3 +91,19 @@ func (s *userQuizPaperService) Generate(users []int64, quizPaper *models.QuizPap
return userQuizPapers
}
func (s *userQuizPaperService) UpdateScore(userquizpaper_id int64) (*models.UserQuizPaper, error) {
score, err := s.userquizRepository.SumScore(userquizpaper_id)
if err != nil {
return nil, err
}
userquizpaper, err := s.repository.Get(userquizpaper_id)
if err != nil {
return nil, err
}
fmt.Println("score", score)
userquizpaper.UserScore = score
return s.repository.Update(userquizpaper)
}