Files
evening_detective_server/internal/services/scenarios_service/service.go
T
2026-07-28 20:38:03 +07:00

200 lines
4.4 KiB
Go

package scenarios_service
import (
"context"
"errors"
"evening_detective_server/internal/modules/cleaner"
"evening_detective_server/internal/modules/storytelling"
"evening_detective_server/internal/repos/scenarios_repo"
"strings"
)
type ScenarioService struct {
scenariosRepo *scenarios_repo.ScenariosRepo
cleaner cleaner.ICleaner
domain string
}
func NewScenarioService(
scenariosRepo *scenarios_repo.ScenariosRepo,
cleaner cleaner.ICleaner,
domain string,
) *ScenarioService {
return &ScenarioService{
scenariosRepo: scenariosRepo,
cleaner: cleaner,
domain: domain,
}
}
func (s *ScenarioService) AddScenario(
ctx context.Context,
name string,
authorId int,
) (int, error) {
id, err := s.scenariosRepo.AddScenario(ctx, name, authorId)
if err != nil {
return 0, err
}
return id, nil
}
func (s *ScenarioService) GetScenariosByAuthorID(
ctx context.Context,
authorId int,
) ([]*Scenario, error) {
scenarios, err := s.scenariosRepo.GetScenariosByAuthorID(ctx, authorId)
if err != nil {
return nil, err
}
return mapScenariosLight(scenarios, s.domain), nil
}
func (s *ScenarioService) GetScenariosCatalog(
ctx context.Context,
) ([]*Scenario, error) {
scenarios, err := s.scenariosRepo.GetScenariosByStatus(ctx, "public")
if err != nil {
return nil, err
}
return mapScenariosLight(scenarios, s.domain), nil
}
func (s *ScenarioService) GetFullScenarioByID(
ctx context.Context,
id int,
) (*Scenario, error) {
scenario, err := s.scenariosRepo.GetScenarioByID(ctx, id)
if err != nil {
return nil, err
}
return mapScenario(scenario, s.domain)
}
func (s *ScenarioService) GetScenarioByID(
ctx context.Context,
id int,
) (*Scenario, error) {
scenario, err := s.scenariosRepo.GetScenarioByID(ctx, id)
if err != nil {
return nil, err
}
return MapScenarioLight(scenario, s.domain), nil
}
func (s *ScenarioService) UpdateScenarioByID(
ctx context.Context,
id int,
name string,
description string,
image string,
) error {
return s.scenariosRepo.UpdateScenarioByID(ctx, id, name, description, image)
}
func (s *ScenarioService) UpdateScenarioStatusByID(
ctx context.Context,
id int,
status string,
) error {
return s.scenariosRepo.UpdateScenarioStatusByID(ctx, id, status)
}
func (s *ScenarioService) DeleteScenarioByID(
ctx context.Context,
id int,
) error {
return s.scenariosRepo.DeleteScenarioByID(ctx, id)
}
func (s *ScenarioService) AddScenarioPlace(
ctx context.Context,
id int,
place *storytelling.Place,
) error {
story, err := s.getStory(ctx, id)
if err != nil {
return err
}
story.Places = append(
[]*storytelling.Place{place},
story.Places...,
)
return s.updateStory(ctx, id, story)
}
func (s *ScenarioService) UpdateScenarioPlace(
ctx context.Context,
id int,
code string,
place *storytelling.Place,
) error {
story, err := s.getStory(ctx, id)
if err != nil {
return err
}
for i := range story.Places {
if story.Places[i].Code == code {
story.Places[i] = place
break
}
}
return s.updateStory(ctx, id, story)
}
func (s *ScenarioService) DeleteScenarioPlace(
ctx context.Context,
id int,
code string,
) error {
story, err := s.getStory(ctx, id)
if err != nil {
return err
}
for i := range story.Places {
if story.Places[i].Code == code {
story.Places = append(story.Places[:i], story.Places[i+1:]...)
break
}
}
return s.updateStory(ctx, id, story)
}
func (s *ScenarioService) getStory(ctx context.Context, id int) (*storytelling.Story, error) {
storyString, err := s.scenariosRepo.GetStoryByScenarioID(ctx, id)
if err != nil {
return nil, err
}
return mapStory(storyString, s.domain)
}
func (s *ScenarioService) updateStory(ctx context.Context, id int, story *storytelling.Story) error {
mapCodes := map[string]struct{}{}
for _, place := range story.Places {
code := s.cleaner.ClearCode(place.Code)
mapCodes[code] = struct{}{}
place.Image = strings.TrimPrefix(place.Image, s.domain)
}
if len(mapCodes) != len(story.Places) {
return errors.New("Такой код точки уже существует")
}
cleanPlaces := make([]*storytelling.Place, 0, len(story.Places))
for _, place := range story.Places {
code := s.cleaner.ClearCode(place.Code)
if code == "" {
continue
}
place.Code = code
cleanPlaces = append(cleanPlaces, place)
}
story.Places = cleanPlaces
storyString, err := convertStory(story)
if err != nil {
return err
}
return s.scenariosRepo.UpdateStoryByScenarioID(ctx, id, storyString)
}