SPMS_API/SPMS.Infrastructure/Persistence/Repositories/DeviceRepository.cs
SEAN 7ffc152536 improvement: 태그 CRUD API 구현 (#186)
- Tag DTO 6종 생성 (List/Create/Update/Delete Request/Response)
- ITagRepository 확장 (GetTagListAsync, CountByServiceAsync)
- IDeviceRepository 확장 (GetDeviceCountsByTagIdsAsync)
- ITagService/TagService 구현 (CRUD 비즈니스 로직)
- TagController 신규 생성 (v1/in/tag/list, create, update, delete)
- DI 등록

Closes #186
2026-02-25 18:07:11 +09:00

150 lines
5.0 KiB
C#

using Microsoft.EntityFrameworkCore;
using SPMS.Domain.Entities;
using SPMS.Domain.Enums;
using SPMS.Domain.Interfaces;
namespace SPMS.Infrastructure.Persistence.Repositories;
public class DeviceRepository : Repository<Device>, IDeviceRepository
{
public DeviceRepository(AppDbContext context) : base(context) { }
public async Task<Device?> GetByServiceAndTokenAsync(long serviceId, string deviceToken)
{
return await _dbSet.FirstOrDefaultAsync(d => d.ServiceId == serviceId && d.DeviceToken == deviceToken);
}
public async Task<Device?> GetByIdAndServiceAsync(long id, long serviceId)
{
return await _dbSet.FirstOrDefaultAsync(d => d.Id == id && d.ServiceId == serviceId);
}
public async Task<int> GetActiveCountByServiceAsync(long serviceId)
{
return await _dbSet.CountAsync(d => d.ServiceId == serviceId && d.IsActive);
}
public async Task<IReadOnlyList<Device>> GetByPlatformAsync(long serviceId, Platform platform)
{
return await _dbSet
.Where(d => d.ServiceId == serviceId && d.Platform == platform && d.IsActive)
.ToListAsync();
}
public async Task<(IReadOnlyList<Device> Items, int TotalCount)> GetPagedAsync(
long? serviceId, int page, int size,
Platform? platform = null, bool? pushAgreed = null,
bool? isActive = null, List<int>? tags = null,
string? keyword = null, bool? marketingAgreed = null)
{
IQueryable<Device> query = _dbSet.Include(d => d.Service);
if (serviceId.HasValue)
query = query.Where(d => d.ServiceId == serviceId.Value);
if (platform.HasValue)
query = query.Where(d => d.Platform == platform.Value);
if (pushAgreed.HasValue)
query = query.Where(d => d.PushAgreed == pushAgreed.Value);
if (isActive.HasValue)
query = query.Where(d => d.IsActive == isActive.Value);
if (marketingAgreed.HasValue)
query = query.Where(d => d.MarketingAgreed == marketingAgreed.Value);
if (!string.IsNullOrWhiteSpace(keyword))
{
var trimmed = keyword.Trim();
if (long.TryParse(trimmed, out var deviceId))
query = query.Where(d => d.Id == deviceId || d.DeviceToken.Contains(trimmed));
else
query = query.Where(d => d.DeviceToken.Contains(trimmed));
}
if (tags != null && tags.Count > 0)
{
foreach (var tag in tags)
{
var tagStr = tag.ToString();
query = query.Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%"));
}
}
var totalCount = await query.CountAsync();
var items = await query
.OrderByDescending(d => d.CreatedAt)
.Skip((page - 1) * size)
.Take(size)
.ToListAsync();
return (items, totalCount);
}
public async Task<IReadOnlyList<Device>> GetAllFilteredAsync(
long? serviceId,
Platform? platform = null, bool? pushAgreed = null,
bool? isActive = null, List<int>? tags = null,
string? keyword = null, bool? marketingAgreed = null)
{
IQueryable<Device> query = _dbSet.Include(d => d.Service);
if (serviceId.HasValue)
query = query.Where(d => d.ServiceId == serviceId.Value);
if (platform.HasValue)
query = query.Where(d => d.Platform == platform.Value);
if (pushAgreed.HasValue)
query = query.Where(d => d.PushAgreed == pushAgreed.Value);
if (isActive.HasValue)
query = query.Where(d => d.IsActive == isActive.Value);
if (marketingAgreed.HasValue)
query = query.Where(d => d.MarketingAgreed == marketingAgreed.Value);
if (!string.IsNullOrWhiteSpace(keyword))
{
var trimmed = keyword.Trim();
if (long.TryParse(trimmed, out var deviceId))
query = query.Where(d => d.Id == deviceId || d.DeviceToken.Contains(trimmed));
else
query = query.Where(d => d.DeviceToken.Contains(trimmed));
}
if (tags != null && tags.Count > 0)
{
foreach (var tag in tags)
{
var tagStr = tag.ToString();
query = query.Where(d => d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%"));
}
}
return await query
.OrderByDescending(d => d.CreatedAt)
.ToListAsync();
}
public async Task<Dictionary<long, int>> GetDeviceCountsByTagIdsAsync(IEnumerable<long> tagIds)
{
var tagIdList = tagIds.ToList();
if (tagIdList.Count == 0)
return new Dictionary<long, int>();
var result = new Dictionary<long, int>();
foreach (var tagId in tagIdList)
{
var tagStr = tagId.ToString();
var count = await _dbSet.CountAsync(d =>
d.Tags != null && EF.Functions.Like(d.Tags, $"%{tagStr}%"));
result[tagId] = count;
}
return result;
}
}