Added new BumperEndpoints to the API for managing bumper templates and variants, enhancing the channel management capabilities. Removed outdated bumper-related commands and handlers from the application, streamlining the codebase and improving maintainability. Updated ChannelEndpoints to reflect these changes and ensure proper routing for the new endpoints.
119 lines
4.5 KiB
C#
119 lines
4.5 KiB
C#
using LiteCqrs;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using TeleWave.Application.Broadcast;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Application.Common.Models;
|
|
using TeleWave.Domain.Programming;
|
|
|
|
namespace TeleWave.Application.Programming.Templates.CopyTemplate;
|
|
|
|
public sealed class CopyTemplateCommandHandler(IAppDbContext dbContext)
|
|
: ICommandHandler<CopyTemplateCommand, Result<CopyTemplateResultDto>>
|
|
{
|
|
public async Task<Result<CopyTemplateResultDto>> Handle(
|
|
CopyTemplateCommand command,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
var target = await dbContext.Channels.FirstOrDefaultAsync(
|
|
c => c.Id == command.TargetChannelId,
|
|
cancellationToken
|
|
);
|
|
if (target is null)
|
|
return Result.Failure<CopyTemplateResultDto>(ChannelErrors.NotFound);
|
|
|
|
var source = await dbContext
|
|
.ScheduleTemplates.AsNoTracking()
|
|
.Include(t => t.Layers)
|
|
.ThenInclude(l => l.Slots)
|
|
.AsSplitQuery()
|
|
.FirstOrDefaultAsync(t => t.ChannelId == command.SourceChannelId, cancellationToken);
|
|
if (source is null)
|
|
return Result.Failure<CopyTemplateResultDto>(ChannelErrors.TemplateNotFound);
|
|
|
|
// Прежняя сетка приёмника заменяется целиком: слить две сетки автоматически нельзя,
|
|
// а «добавить поверх» дало бы кашу из пересекающихся слотов.
|
|
var existing = await dbContext
|
|
.ScheduleTemplates.Where(t => t.ChannelId == target.Id)
|
|
.ToListAsync(cancellationToken);
|
|
dbContext.ScheduleTemplates.RemoveRange(existing);
|
|
|
|
var copyTemplate = ScheduleTemplate.Create(target.Id, source.Name);
|
|
copyTemplate.SetFallbackGroup(source.FallbackGroupId);
|
|
copyTemplate.SetRules(source.RulesJson);
|
|
// Стыки и заставки общие для всех каналов — копия ссылается на те же, без перевешивания.
|
|
copyTemplate.SetDefaultJunction(source.DefaultJunctionId);
|
|
|
|
var (layers, slots) = CopyGrid(source, copyTemplate);
|
|
|
|
dbContext.ScheduleTemplates.Add(copyTemplate);
|
|
target.SetTemplate(copyTemplate.Id);
|
|
|
|
return Result.Success(new CopyTemplateResultDto(layers, slots));
|
|
}
|
|
|
|
/// <summary>Переносит слои со слотами. Возвращает, сколько слоёв (кроме фонового) и слотов скопировано.</summary>
|
|
private static (int Layers, int Slots) CopyGrid(
|
|
ScheduleTemplate source,
|
|
ScheduleTemplate copyTemplate
|
|
)
|
|
{
|
|
var layers = 0;
|
|
var slots = 0;
|
|
|
|
foreach (var layer in source.Layers.OrderByDescending(l => l.Priority))
|
|
{
|
|
// Фоновый слой у нового шаблона уже есть — в него переносим слоты, а не заводим второй.
|
|
var copyLayer = layer.IsBackground
|
|
? copyTemplate.Background!
|
|
: copyTemplate.AddLayer(layer.Name, layer.Priority);
|
|
copyLayer.Update(layer.Name, layer.Priority, layer.ApplicabilityJson, layer.IsEnabled);
|
|
if (!layer.IsBackground)
|
|
layers++;
|
|
|
|
foreach (var slot in layer.Slots)
|
|
{
|
|
CopySlot(slot, copyLayer);
|
|
slots++;
|
|
}
|
|
}
|
|
|
|
return (layers, slots);
|
|
}
|
|
|
|
private static void CopySlot(Slot slot, GridLayer copyLayer)
|
|
{
|
|
var copySlot = copyLayer.AddSlot(
|
|
slot.Title,
|
|
slot.TargetStart,
|
|
slot.TargetDurationMinutes,
|
|
slot.Daypart,
|
|
slot.SlotKind,
|
|
slot.Weekday
|
|
);
|
|
copySlot.UpdateTiming(
|
|
slot.Weekday,
|
|
slot.TargetStart,
|
|
slot.TargetDurationMinutes,
|
|
slot.Daypart,
|
|
slot.IsAnchor,
|
|
slot.MaxDriftMinutes,
|
|
slot.SnapToMinutes
|
|
);
|
|
copySlot.UpdateContent(
|
|
new SlotContent(
|
|
slot.Title,
|
|
slot.SlotKind,
|
|
slot.GroupId,
|
|
slot.StrategyJson,
|
|
slot.RepeatSourceJson,
|
|
slot.BlockMode,
|
|
slot.BlockValue,
|
|
slot.OverflowPolicy,
|
|
slot.JunctionBetweenId,
|
|
slot.JunctionAfterId
|
|
)
|
|
);
|
|
}
|
|
}
|