core/internal/controllers/http_controllers/result/result.go

246 lines
7.1 KiB
Go
Raw Normal View History

2024-10-25 15:26:03 +00:00
package result
2024-02-19 17:48:04 +00:00
import (
"bytes"
2025-02-24 17:06:12 +00:00
"gitea.pena/SQuiz/common/dal"
"gitea.pena/SQuiz/common/middleware"
"gitea.pena/SQuiz/common/model"
"gitea.pena/SQuiz/common/repository/result"
2024-02-19 17:48:04 +00:00
"github.com/gofiber/fiber/v2"
2025-02-24 17:06:12 +00:00
"gitea.pena/SQuiz/core/internal/tools"
2024-02-19 17:48:04 +00:00
"strconv"
"time"
)
2024-10-25 15:26:03 +00:00
type Deps struct {
DAL *dal.DAL
S3Prefix string
}
type Result struct {
dal *dal.DAL
s3Prefix string
}
func NewResultController(deps Deps) *Result {
return &Result{
dal: deps.DAL,
s3Prefix: deps.S3Prefix,
}
}
2024-02-19 17:48:04 +00:00
type ReqExport struct {
To, From time.Time
New bool
Page uint64
Limit uint64
}
type ReqExportResponse struct {
TotalCount uint64 `json:"total_count"`
Results []model.AnswerExport `json:"results"`
}
2024-10-25 15:26:03 +00:00
func (r *Result) GetResultsByQuizID(ctx *fiber.Ctx) error {
2024-02-19 17:48:04 +00:00
payment := true // параметр для определения существования текущих привилегий юзера
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
}
var req ReqExport
if err := ctx.BodyParser(&req); err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
}
quizIDStr := ctx.Params("quizId")
quizID, err := strconv.ParseUint(quizIDStr, 10, 64)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid quiz ID format")
}
2024-10-25 15:26:03 +00:00
account, err := r.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
2024-03-13 16:57:12 +00:00
if _, cnt := account.Privileges["quizCnt"]; !cnt {
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
payment = false
}
2024-02-19 17:48:04 +00:00
}
2024-10-25 15:26:03 +00:00
results, totalCount, err := r.dal.ResultRepo.GetQuizResults(ctx.Context(), quizID, result.GetQuizResDeps{
2024-02-19 17:48:04 +00:00
To: req.To,
From: req.From,
New: req.New,
Page: req.Page,
Limit: req.Limit,
}, payment)
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
resp := &ReqExportResponse{
TotalCount: totalCount,
Results: results,
}
return ctx.Status(fiber.StatusOK).JSON(resp)
}
2024-10-25 15:26:03 +00:00
func (r *Result) DelResultByID(ctx *fiber.Ctx) error {
2024-02-19 17:48:04 +00:00
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return ctx.Status(fiber.StatusUnauthorized).SendString("could not get account ID from token")
}
resultIDStr := ctx.Params("resultId")
resultID, err := strconv.ParseUint(resultIDStr, 10, 64)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid result ID format")
}
2024-10-25 15:26:03 +00:00
isOwner, err := r.dal.ResultRepo.CheckResultOwner(ctx.Context(), resultID, accountID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
if !isOwner {
return ctx.Status(fiber.StatusUnauthorized).SendString("not the owner of the result")
}
2024-10-25 15:26:03 +00:00
if err := r.dal.ResultRepo.SoftDeleteResultByID(ctx.Context(), resultID); err != nil {
2024-02-19 17:48:04 +00:00
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
ctx.Status(fiber.StatusOK)
return nil
}
type ReqSeen struct {
Answers []int64
}
2024-10-25 15:26:03 +00:00
func (r *Result) SetStatus(ctx *fiber.Ctx) error {
2024-02-19 17:48:04 +00:00
var req ReqSeen
if err := ctx.BodyParser(&req); err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("Invalid request data")
}
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return ctx.Status(fiber.StatusUnauthorized).SendString("could not get account ID from token")
}
2024-10-25 15:26:03 +00:00
answers, err := r.dal.ResultRepo.CheckResultsOwner(ctx.Context(), req.Answers, accountID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
if len(answers) != len(req.Answers) {
return ctx.Status(fiber.StatusNotAcceptable).SendString("could not update some answers because you don't have rights")
}
2024-10-25 15:26:03 +00:00
if err := r.dal.ResultRepo.UpdateAnswersStatus(ctx.Context(), accountID, answers); err != nil {
2024-02-19 17:48:04 +00:00
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
return ctx.Status(fiber.StatusOK).JSON(nil)
}
2024-10-25 15:26:03 +00:00
func (r *Result) ExportResultsToCSV(ctx *fiber.Ctx) error {
2024-02-19 17:48:04 +00:00
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
}
quizIDStr := ctx.Params("quizID")
quizID, err := strconv.ParseUint(quizIDStr, 10, 64)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
}
req := ReqExport{}
if err := ctx.BodyParser(&req); err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("invalid request body")
}
2024-10-25 15:26:03 +00:00
account, err := r.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
2024-03-13 16:57:12 +00:00
if _, cnt := account.Privileges["quizCnt"]; !cnt {
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
return ctx.Status(fiber.StatusPaymentRequired).SendString("payment required")
}
2024-02-19 17:48:04 +00:00
}
2024-10-25 15:26:03 +00:00
quiz, err := r.dal.QuizRepo.GetQuizById(ctx.Context(), accountID, quizID)
2024-07-19 12:46:40 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get quiz")
}
2024-10-25 15:26:03 +00:00
questions, err := r.dal.ResultRepo.GetQuestions(ctx.Context(), quizID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get questions")
}
2024-10-25 15:26:03 +00:00
answers, err := r.dal.ResultRepo.GetQuizResultsCSV(ctx.Context(), quizID, result.GetQuizResDeps{
2024-02-19 17:48:04 +00:00
To: req.To,
From: req.From,
New: req.New,
Page: req.Page,
Limit: req.Limit,
})
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get quiz results")
}
buffer := new(bytes.Buffer)
2024-10-25 15:26:03 +00:00
if err := tools.WriteDataToExcel(buffer, questions, answers, r.s3Prefix+quiz.Qid+"/"); err != nil {
2024-02-19 17:48:04 +00:00
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to write data to Excel")
}
ctx.Set(fiber.HeaderContentType, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
ctx.Set(fiber.HeaderContentDisposition, `attachment; filename="results.xlsx"`)
return ctx.Send(buffer.Bytes())
}
2024-10-25 15:26:03 +00:00
func (r *Result) GetResultAnswers(ctx *fiber.Ctx) error {
2024-02-19 17:48:04 +00:00
accountID, ok := middleware.GetAccountId(ctx)
if !ok {
return ctx.Status(fiber.StatusUnauthorized).SendString("account id is required")
}
resultID, err := strconv.ParseUint(ctx.Params("resultID"), 10, 64)
if err != nil {
return ctx.Status(fiber.StatusBadRequest).SendString("invalid quiz ID")
}
2024-10-25 15:26:03 +00:00
account, err := r.dal.AccountRepo.GetAccountByID(ctx.Context(), accountID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString(err.Error())
}
2024-03-13 16:57:12 +00:00
if _, cnt := account.Privileges["quizCnt"]; !cnt {
if _, unlim := account.Privileges["quizUnlimTime"]; !unlim {
return ctx.Status(fiber.StatusPaymentRequired).SendString("payment required")
}
2024-02-19 17:48:04 +00:00
}
2024-10-25 15:26:03 +00:00
answers, err := r.dal.ResultRepo.GetResultAnswers(ctx.Context(), resultID)
2024-02-19 17:48:04 +00:00
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("failed to get result answers")
}
2024-10-25 15:26:03 +00:00
sortedAnswers, err := r.dal.QuestionRepo.ForSortingResults(ctx.Context(), answers)
if err != nil {
return ctx.Status(fiber.StatusInternalServerError).SendString("failed sort result answers")
}
2024-02-19 17:48:04 +00:00
return ctx.JSON(sortedAnswers)
2024-02-19 17:48:04 +00:00
}