149 lines
5.4 KiB
C#
149 lines
5.4 KiB
C#
using System.Linq.Expressions;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using SPMS.Domain.Entities;
|
|
using SPMS.Domain.Enums;
|
|
using SPMS.Domain.Interfaces;
|
|
|
|
namespace SPMS.Infrastructure.Persistence.Repositories;
|
|
|
|
public class MessageRepository : Repository<Message>, IMessageRepository
|
|
{
|
|
public MessageRepository(AppDbContext context) : base(context) { }
|
|
|
|
public async Task<Message?> GetByMessageCodeAsync(string messageCode)
|
|
{
|
|
return await _dbSet
|
|
.FirstOrDefaultAsync(m => m.MessageCode == messageCode && !m.IsDeleted);
|
|
}
|
|
|
|
public async Task<Message?> GetByMessageCodeAndServiceAsync(string messageCode, long serviceId)
|
|
{
|
|
return await _dbSet
|
|
.FirstOrDefaultAsync(m => m.MessageCode == messageCode && m.ServiceId == serviceId && !m.IsDeleted);
|
|
}
|
|
|
|
public async Task<int> GetTodaySequenceAsync(long serviceId)
|
|
{
|
|
var todayStart = DateTime.UtcNow.Date;
|
|
var todayEnd = todayStart.AddDays(1);
|
|
|
|
return await _dbSet
|
|
.CountAsync(m => m.ServiceId == serviceId
|
|
&& m.CreatedAt >= todayStart
|
|
&& m.CreatedAt < todayEnd);
|
|
}
|
|
|
|
public async Task<(IReadOnlyList<Message> Items, int TotalCount)> GetPagedByServiceAsync(
|
|
long serviceId, int page, int size,
|
|
Expression<Func<Message, bool>>? predicate = null)
|
|
{
|
|
var query = _dbSet
|
|
.Where(m => m.ServiceId == serviceId && !m.IsDeleted);
|
|
|
|
if (predicate != null)
|
|
query = query.Where(predicate);
|
|
|
|
var totalCount = await query.CountAsync();
|
|
|
|
var items = await query
|
|
.OrderByDescending(m => m.CreatedAt)
|
|
.Skip((page - 1) * size)
|
|
.Take(size)
|
|
.ToListAsync();
|
|
|
|
return (items, totalCount);
|
|
}
|
|
|
|
public async Task<Message?> GetByMessageCodeWithDetailsAsync(string messageCode, long serviceId)
|
|
{
|
|
return await _dbSet
|
|
.Include(m => m.Service)
|
|
.Include(m => m.CreatedByAdmin)
|
|
.FirstOrDefaultAsync(m => m.MessageCode == messageCode && m.ServiceId == serviceId && !m.IsDeleted);
|
|
}
|
|
|
|
public async Task<(int TotalSendCount, int SuccessCount)> GetSendStatsAsync(long messageId)
|
|
{
|
|
var stats = await _context.PushSendLogs
|
|
.Where(l => l.MessageId == messageId)
|
|
.GroupBy(_ => 1)
|
|
.Select(g => new
|
|
{
|
|
Total = g.Count(),
|
|
Success = g.Count(l => l.Status == PushResult.Success)
|
|
})
|
|
.FirstOrDefaultAsync();
|
|
|
|
return stats != null ? (stats.Total, stats.Success) : (0, 0);
|
|
}
|
|
|
|
public async Task<IReadOnlyList<MessageListProjection>> GetTopBySendCountAsync(long? serviceId, int count)
|
|
{
|
|
var query = _dbSet.Where(m => !m.IsDeleted);
|
|
if (serviceId.HasValue)
|
|
query = query.Where(m => m.ServiceId == serviceId.Value);
|
|
|
|
return await query.Select(m => new MessageListProjection
|
|
{
|
|
MessageCode = m.MessageCode,
|
|
Title = m.Title,
|
|
IsActive = !m.IsDeleted,
|
|
CreatedAt = m.CreatedAt,
|
|
ServiceName = m.Service.ServiceName,
|
|
ServiceCode = m.Service.ServiceCode,
|
|
TotalSendCount = _context.PushSendLogs.Count(l => l.MessageId == m.Id),
|
|
SuccessCount = _context.PushSendLogs.Count(l => l.MessageId == m.Id && l.Status == PushResult.Success)
|
|
})
|
|
.Where(p => p.TotalSendCount > 0)
|
|
.OrderByDescending(p => p.TotalSendCount)
|
|
.Take(count)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<(IReadOnlyList<MessageListProjection> Items, int TotalCount)> GetPagedForListAsync(
|
|
long? serviceId, int page, int size,
|
|
string? keyword = null, bool? isActive = null, string? sendStatus = null)
|
|
{
|
|
var query = _dbSet.Where(m => !m.IsDeleted);
|
|
|
|
if (serviceId.HasValue)
|
|
query = query.Where(m => m.ServiceId == serviceId.Value);
|
|
|
|
if (!string.IsNullOrWhiteSpace(keyword))
|
|
query = query.Where(m => m.Title.Contains(keyword) || m.Body.Contains(keyword));
|
|
|
|
if (isActive.HasValue)
|
|
query = query.Where(m => m.IsDeleted != isActive.Value);
|
|
|
|
var projected = query.Select(m => new MessageListProjection
|
|
{
|
|
MessageCode = m.MessageCode,
|
|
Title = m.Title,
|
|
IsActive = !m.IsDeleted,
|
|
CreatedAt = m.CreatedAt,
|
|
ServiceName = m.Service.ServiceName,
|
|
ServiceCode = m.Service.ServiceCode,
|
|
TotalSendCount = _context.PushSendLogs.Count(l => l.MessageId == m.Id),
|
|
SuccessCount = _context.PushSendLogs.Count(l => l.MessageId == m.Id && l.Status == PushResult.Success)
|
|
});
|
|
|
|
// 발송 상태 필터 (SendStatus 상수 사용 — PRD FR-MSG-006)
|
|
if (sendStatus == SendStatus.Complete)
|
|
projected = projected.Where(p => p.SuccessCount > 0);
|
|
else if (sendStatus == SendStatus.Failed)
|
|
projected = projected.Where(p => p.TotalSendCount > 0 && p.SuccessCount == 0);
|
|
else if (sendStatus == SendStatus.Pending)
|
|
projected = projected.Where(p => p.TotalSendCount == 0);
|
|
|
|
var totalCount = await projected.CountAsync();
|
|
|
|
var items = await projected
|
|
.OrderByDescending(p => p.CreatedAt)
|
|
.Skip((page - 1) * size)
|
|
.Take(size)
|
|
.ToListAsync();
|
|
|
|
return (items, totalCount);
|
|
}
|
|
}
|