cab-backend/internal/handlers/game_modules.go
2026-03-30 21:00:35 +03:00

195 lines
4.5 KiB
Go

package handlers
import (
"context"
"net/http"
"strconv"
"strings"
"time"
"game-admin/internal/models"
"github.com/gin-gonic/gin"
"github.com/uptrace/bun"
)
func (h *GameHandler) ListModules(c *gin.Context) {
var modules []models.Module
err := h.db.NewSelect().
Model(&modules).
OrderExpr("id ASC").
Scan(c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, modules)
}
func (h *GameHandler) ListGameModules(c *gin.Context) {
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
return
}
exists, err := h.gameExists(c, gameID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if !exists {
c.JSON(http.StatusNotFound, gin.H{"error": "Game not found"})
return
}
modulesByGame, err := h.loadModulesByGameIDs(c, []int64{gameID})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, modulesByGame[gameID])
}
func (h *GameHandler) ConnectModule(c *gin.Context) {
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
return
}
var req models.ConnectGameModuleRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
exists, err := h.gameExists(c, gameID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if !exists {
c.JSON(http.StatusNotFound, gin.H{"error": "Game not found"})
return
}
module := new(models.Module)
err = h.db.NewSelect().
Model(module).
Where(`"key" = ?`, strings.TrimSpace(req.ModuleKey)).
Scan(c)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Module not found"})
return
}
gameModule := &models.GameModule{
GameID: gameID,
ModuleID: module.ID,
CreatedAt: time.Now(),
}
_, err = h.db.NewInsert().Model(gameModule).Exec(c)
if err != nil {
c.JSON(http.StatusConflict, gin.H{"error": "Module already connected to game"})
return
}
c.JSON(http.StatusCreated, module)
}
func (h *GameHandler) DisconnectModule(c *gin.Context) {
gameID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid game id"})
return
}
moduleKey := c.Param("module_key")
module := new(models.Module)
err = h.db.NewSelect().
Model(module).
Where(`"key" = ?`, moduleKey).
Scan(c)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Module not found"})
return
}
res, err := h.db.NewDelete().
Model((*models.GameModule)(nil)).
Where("game_id = ? AND module_id = ?", gameID, module.ID).
Exec(c)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
if affected, _ := res.RowsAffected(); affected == 0 {
c.JSON(http.StatusNotFound, gin.H{"error": "Module is not connected to game"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Module disconnected"})
}
func (h *GameHandler) attachModulesToGames(c *gin.Context, games []models.Game) error {
if len(games) == 0 {
return nil
}
gameIDs := make([]int64, 0, len(games))
for _, game := range games {
gameIDs = append(gameIDs, game.ID)
}
modulesByGame, err := h.loadModulesByGameIDs(c, gameIDs)
if err != nil {
return err
}
for i := range games {
games[i].Modules = modulesByGame[games[i].ID]
}
return nil
}
func (h *GameHandler) loadModulesByGameIDs(c *gin.Context, gameIDs []int64) (map[int64][]models.Module, error) {
var gameModules []models.GameModule
err := h.db.NewSelect().
Model(&gameModules).
Relation("Module").
Where("gm.game_id IN (?)", bun.In(gameIDs)).
OrderExpr("gm.id ASC").
Scan(c)
if err != nil {
return nil, err
}
modulesByGame := make(map[int64][]models.Module, len(gameIDs))
for _, gameID := range gameIDs {
modulesByGame[gameID] = []models.Module{}
}
for _, gameModule := range gameModules {
if gameModule.Module == nil {
continue
}
modulesByGame[gameModule.GameID] = append(modulesByGame[gameModule.GameID], *gameModule.Module)
}
return modulesByGame, nil
}
func (h *GameHandler) gameHasModule(ctx context.Context, gameID int64, moduleKey string) (bool, error) {
return h.db.NewSelect().
Model((*models.GameModule)(nil)).
Join("JOIN modules AS m ON m.id = gm.module_id").
Where("gm.game_id = ?", gameID).
Where(`m."key" = ?`, moduleKey).
Exists(ctx)
}