using Application.Abstractions.Messaging; using Application.Abstractions.Data; using Domain.Entities.Forum.ValueObject; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Forum.Post.Search; public sealed class Handler(IAppDbContext db) : IQueryHandler { public async Task Handle(Query request, CancellationToken ct) { var query = db.Post.AsNoTracking().Include(c => c.Board).AsQueryable(); if (request.BoardID.HasValue) { query = query.Where(c => c.BoardID == request.BoardID.Value); } if (request.BoardPrefixID.HasValue) { query = query.Where(c => c.BoardPrefixID == request.BoardPrefixID.Value); } if (!string.IsNullOrWhiteSpace(request.Keyword)) { var kw = request.Keyword.Trim(); query = request.Search switch { 0 => query.Where(c => c.Subject.Contains(kw)), 1 => query.Where(c => c.Content.Contains(kw)), 2 => query.Where(c => (c.Name != null && c.Name.Contains(kw)) || (c.SID != null && c.SID.Contains(kw))), _ => query.Where(c => c.Subject.Contains(kw) || c.Content.Contains(kw)) }; } if (!string.IsNullOrWhiteSpace(request.StartAt) && DateTime.TryParse(request.StartAt, out var startDate)) { query = query.Where(c => c.CreatedAt >= startDate); } if (!string.IsNullOrWhiteSpace(request.EndAt) && DateTime.TryParse(request.EndAt, out var endDate)) { query = query.Where(c => c.CreatedAt <= endDate.AddDays(1)); } if (request.IsNotice == true) { query = query.Where(c => c.IsNotice); } if (request.IsSecret == true) { query = query.Where(c => c.IsSecret); } if (request.IsReply == true) { query = query.Where(c => c.IsReply); } if (request.IsDeleted == true) { query = query.Where(c => c.IsDeleted); } if (request.IsQnA == true) { query = query.Where(c => c.Board.BoardMeta.List.Layout == BoardLayout.QnA); } query = request.Sort switch { 1 => query.OrderByDescending(c => c.Views), 2 => query.OrderByDescending(c => c.Comments), 3 => query.OrderByDescending(c => c.Likes), _ => query.OrderByDescending(c => c.ID) }; var total = await query.CountAsync(ct); var list = await query .Skip((request.PageNum - 1) * request.PerPage) .Take(request.PerPage) .Select(c => new { c.ID, c.BoardID, BoardName = c.Board.Name, BoardPrefixName = c.BoardPrefix != null ? c.BoardPrefix.Name : null, c.BoardPrefixID, c.Subject, c.Thumbnail, c.Name, c.SID, c.IsNotice, c.IsSecret, c.IsReply, c.IsSpeaker, c.IsAnonymous, c.IsDeleted, IsQnA = c.Board.BoardMeta.List.Layout == BoardLayout.QnA, c.Views, c.Likes, c.Dislikes, c.Comments, c.Images, c.Medias, c.Files, c.Tags, c.UpdatedAt, c.CreatedAt }) .ToListAsync(ct); var startNum = total - ((request.PageNum - 1) * request.PerPage); return new Response( total, [..list.Select((c, i) => new Response.Row( Num: startNum - i, c.ID, c.BoardID, c.BoardName, c.BoardPrefixName, c.BoardPrefixID, c.Subject, c.Thumbnail, c.Name, c.SID, c.IsNotice, c.IsSecret, c.IsReply, c.IsSpeaker, c.IsAnonymous, c.IsDeleted, c.IsQnA, c.Views, c.Likes, c.Dislikes, c.Comments, c.Images, c.Medias, c.Files, c.Tags, c.UpdatedAt, c.CreatedAt ))] ); } }