197 lines
4.2 KiB
Go
197 lines
4.2 KiB
Go
package controller
|
|
|
|
import (
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/labstack/echo/v4"
|
|
"gitrepo.ru/neonxp/nquest/api"
|
|
"gitrepo.ru/neonxp/nquest/pkg/contextlib"
|
|
"gitrepo.ru/neonxp/nquest/pkg/models"
|
|
"gitrepo.ru/neonxp/nquest/pkg/service"
|
|
)
|
|
|
|
type Admin struct {
|
|
GameService *service.Game
|
|
}
|
|
|
|
// (POST /games/{uid})
|
|
func (a *Admin) AdminEditGame(ctx echo.Context) error {
|
|
user := contextlib.GetUser(ctx)
|
|
req := &api.AdminEditGameJSONRequestBody{}
|
|
|
|
if err := ctx.Bind(req); err != nil {
|
|
return err
|
|
}
|
|
|
|
game := a.mapCreateGameRequest(req, user)
|
|
|
|
game, err := a.GameService.UpsertGame(ctx.Request().Context(), game)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tasks := make([]api.TaskEdit, 0, len(game.Tasks))
|
|
|
|
for _, t := range game.Tasks {
|
|
t := t
|
|
codes := make([]api.CodeEdit, 0, len(t.Codes))
|
|
for _, c := range t.Codes {
|
|
codes = append(codes, api.CodeEdit{
|
|
Id: &c.ID,
|
|
Code: c.Code,
|
|
Description: &c.Description,
|
|
})
|
|
}
|
|
tasks = append(tasks, api.TaskEdit{
|
|
Id: &t.ID,
|
|
Codes: codes,
|
|
Text: t.Text,
|
|
Title: t.Title,
|
|
})
|
|
}
|
|
|
|
return ctx.JSON(http.StatusOK, api.GameAdminResponse{
|
|
Description: game.Description,
|
|
Icon: game.IconID,
|
|
Id: &game.ID,
|
|
Points: game.Points,
|
|
Tasks: tasks,
|
|
Title: game.Title,
|
|
Type: api.MapGameTypeReverse(game.Type),
|
|
Visible: game.Visible,
|
|
})
|
|
}
|
|
|
|
// (GET /games/{uid})
|
|
func (a *Admin) AdminGetGame(ctx echo.Context, uid uuid.UUID) error {
|
|
user := contextlib.GetUser(ctx)
|
|
|
|
game, err := a.GameService.GetByID(ctx.Request().Context(), uid)
|
|
if err != nil {
|
|
return echo.ErrNotFound
|
|
}
|
|
if user.Role != models.RoleAdmin {
|
|
isAuthor := false
|
|
for _, u := range game.Authors {
|
|
if u.ID == user.ID {
|
|
isAuthor = true
|
|
break
|
|
}
|
|
}
|
|
if !isAuthor {
|
|
return echo.ErrForbidden
|
|
}
|
|
}
|
|
|
|
tasks := make([]api.TaskEdit, 0, len(game.Tasks))
|
|
|
|
for _, t := range game.Tasks {
|
|
t := t
|
|
codes := make([]api.CodeEdit, 0, len(t.Codes))
|
|
for _, c := range t.Codes {
|
|
codes = append(codes, api.CodeEdit{
|
|
Id: &c.ID,
|
|
Code: c.Code,
|
|
Description: &c.Description,
|
|
})
|
|
}
|
|
tasks = append(tasks, api.TaskEdit{
|
|
Id: &t.ID,
|
|
Codes: codes,
|
|
Text: t.Text,
|
|
Title: t.Title,
|
|
})
|
|
}
|
|
|
|
return ctx.JSON(http.StatusOK, api.GameAdminResponse{
|
|
Description: game.Description,
|
|
Icon: game.IconID,
|
|
Id: &game.ID,
|
|
Points: game.Points,
|
|
Tasks: tasks,
|
|
Title: game.Title,
|
|
Type: api.MapGameTypeReverse(game.Type),
|
|
Visible: game.Visible,
|
|
})
|
|
}
|
|
|
|
func (a *Admin) AdminListGames(ctx echo.Context) error {
|
|
user := contextlib.GetUser(ctx)
|
|
|
|
games, err := a.GameService.ListByAuthor(ctx.Request().Context(), user)
|
|
if err != nil {
|
|
return echo.ErrNotFound
|
|
}
|
|
|
|
resp := make(api.GameListResponse, 0, len(games))
|
|
for _, game := range games {
|
|
gv := api.GameView{
|
|
Id: game.ID,
|
|
Title: game.Title,
|
|
Type: api.MapGameTypeReverse(game.Type),
|
|
Points: game.Points,
|
|
TaskCount: len(game.Tasks),
|
|
CreatedAt: game.CreatedAt.Format(time.RFC3339),
|
|
Icon: game.IconID,
|
|
Visible: &game.Visible,
|
|
}
|
|
resp = append(resp, gv)
|
|
}
|
|
|
|
return ctx.JSON(http.StatusOK, resp)
|
|
}
|
|
|
|
func (*Admin) mapCreateGameRequest(req *api.GameEdit, user *models.User) *models.Game {
|
|
id := uuid.New()
|
|
if req.Id != nil {
|
|
id = *req.Id
|
|
}
|
|
|
|
game := &models.Game{
|
|
ID: id,
|
|
Visible: req.Visible,
|
|
Title: req.Title,
|
|
Description: req.Description,
|
|
Authors: []*models.User{
|
|
// user,
|
|
},
|
|
Type: api.MapGameType(req.Type),
|
|
Tasks: make([]*models.Task, 0, len(req.Tasks)),
|
|
Points: req.Points,
|
|
IconID: req.Icon,
|
|
}
|
|
for order, te := range req.Tasks {
|
|
id := uuid.New()
|
|
if te.Id != nil {
|
|
id = *te.Id
|
|
}
|
|
task := &models.Task{
|
|
ID: id,
|
|
Title: te.Title,
|
|
Text: te.Text,
|
|
Codes: make([]*models.Code, 0, len(te.Codes)),
|
|
TaskOrder: uint(order),
|
|
}
|
|
|
|
for _, ce := range te.Codes {
|
|
id := uuid.New()
|
|
if ce.Id != nil {
|
|
id = *ce.Id
|
|
}
|
|
desc := ""
|
|
if ce.Description != nil {
|
|
desc = *ce.Description
|
|
}
|
|
task.Codes = append(task.Codes, &models.Code{
|
|
ID: id,
|
|
Code: ce.Code,
|
|
Description: desc,
|
|
})
|
|
}
|
|
game.Tasks = append(game.Tasks, task)
|
|
}
|
|
|
|
return game
|
|
}
|