56 lines
2.3 KiB
C#
56 lines
2.3 KiB
C#
using LiteCqrs;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using TeleWave.Application.Common.Interfaces;
|
|
using TeleWave.Domain.Library;
|
|
|
|
namespace TeleWave.Application.Library.Interstitials.ListInterstitialBlocks;
|
|
|
|
public sealed class ListInterstitialBlocksQueryHandler(IAppDbContext dbContext)
|
|
: IQueryHandler<ListInterstitialBlocksQuery, IReadOnlyList<InterstitialBlockDto>>
|
|
{
|
|
public async Task<IReadOnlyList<InterstitialBlockDto>> Handle(
|
|
ListInterstitialBlocksQuery query,
|
|
CancellationToken cancellationToken
|
|
)
|
|
{
|
|
var collections = await dbContext
|
|
.Collections.AsNoTracking()
|
|
.Include(c => c.Items)
|
|
.OrderBy(c => c.Name)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
// «Блок» — не отдельная сущность, а признак состава: коллекция целиком из роликов. Смешанные
|
|
// коллекции (франшизы) остаются на своём экране и сюда не попадают.
|
|
var showIds = collections.SelectMany(c => c.Items.Select(i => i.ShowId)).Distinct().ToList();
|
|
var clips = await dbContext
|
|
.Shows.AsNoTracking()
|
|
.Where(s => showIds.Contains(s.Id) && s.Kind == ShowKind.Interstitial)
|
|
.Select(s => new
|
|
{
|
|
s.Id,
|
|
AssetIds = s.Episodes.Select(e => e.MediaAssetId).ToList(),
|
|
})
|
|
.ToDictionaryAsync(s => s.Id, s => s.AssetIds, cancellationToken);
|
|
|
|
var assetIds = clips.Values.SelectMany(ids => ids).Distinct().ToList();
|
|
var durations = await dbContext
|
|
.MediaAssets.AsNoTracking()
|
|
.Where(a => assetIds.Contains(a.Id) && a.Duration != null)
|
|
.Select(a => new { a.Id, a.Duration })
|
|
.ToDictionaryAsync(a => a.Id, a => a.Duration!.Value.TotalSeconds, cancellationToken);
|
|
|
|
return collections
|
|
.Where(c => c.Items.Count > 0 && c.Items.All(i => clips.ContainsKey(i.ShowId)))
|
|
.Select(c => new InterstitialBlockDto(
|
|
c.Id,
|
|
c.Name,
|
|
c.Items.Count,
|
|
c.Items.Sum(i =>
|
|
clips[i.ShowId]
|
|
.Sum(assetId => durations.TryGetValue(assetId, out var d) ? d : 0)
|
|
)
|
|
))
|
|
.ToList();
|
|
}
|
|
}
|