127 lines
4.2 KiB
C#
127 lines
4.2 KiB
C#
using AutoMapper;
|
|
using GreenHome.Application;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GreenHome.Infrastructure;
|
|
|
|
public sealed class DeviceService : IDeviceService
|
|
{
|
|
private readonly GreenHomeDbContext dbContext;
|
|
private readonly IMapper mapper;
|
|
|
|
public DeviceService(GreenHomeDbContext dbContext, IMapper mapper)
|
|
{
|
|
this.dbContext = dbContext;
|
|
this.mapper = mapper;
|
|
}
|
|
|
|
public async Task<int> AddDeviceAsync(DeviceDto dto, CancellationToken cancellationToken)
|
|
{
|
|
var entity = mapper.Map<Domain.Device>(dto);
|
|
dbContext.Devices.Add(entity);
|
|
await dbContext.SaveChangesAsync(cancellationToken);
|
|
return entity.Id;
|
|
}
|
|
|
|
public async Task<IReadOnlyList<DeviceDto>> ListAsync(CancellationToken cancellationToken)
|
|
{
|
|
var items = await dbContext.Devices
|
|
.AsNoTracking()
|
|
.Include(d => d.User)
|
|
.OrderBy(d => d.DeviceName)
|
|
.ToListAsync(cancellationToken);
|
|
return mapper.Map<IReadOnlyList<DeviceDto>>(items);
|
|
}
|
|
|
|
public async Task<DeviceDto> GetDeviceId(string deviceName,CancellationToken cancellationToken)
|
|
{
|
|
var item = await dbContext.Devices
|
|
.AsNoTracking()
|
|
.Include(d => d.User)
|
|
.Where(d=>d.DeviceName==deviceName)
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
return mapper.Map<DeviceDto>(item);
|
|
}
|
|
|
|
public async Task<IReadOnlyList<DeviceDto>> GetUserDevicesAsync(int userId, CancellationToken cancellationToken)
|
|
{
|
|
var items = await dbContext.Devices
|
|
.AsNoTracking()
|
|
.Include(d => d.User)
|
|
.Where(d => d.UserId == userId)
|
|
.OrderBy(d => d.DeviceName)
|
|
.ToListAsync(cancellationToken);
|
|
return mapper.Map<IReadOnlyList<DeviceDto>>(items);
|
|
}
|
|
|
|
public async Task<PagedResult<DeviceDto>> GetDevicesAsync(DeviceFilter filter, CancellationToken cancellationToken)
|
|
{
|
|
if (!filter.UserId.HasValue)
|
|
{
|
|
throw new ArgumentException("UserId is required", nameof(filter));
|
|
}
|
|
|
|
// Get user and role
|
|
var user = await dbContext.Users
|
|
.AsNoTracking()
|
|
.FirstOrDefaultAsync(u => u.Id == filter.UserId.Value, cancellationToken);
|
|
|
|
if (user == null)
|
|
{
|
|
return new PagedResult<DeviceDto>
|
|
{
|
|
Items = Array.Empty<DeviceDto>(),
|
|
TotalCount = 0,
|
|
Page = filter.Page,
|
|
PageSize = filter.PageSize
|
|
};
|
|
}
|
|
|
|
// Build query based on role
|
|
IQueryable<Domain.Device> query = dbContext.Devices
|
|
.AsNoTracking()
|
|
.Include(d => d.User);
|
|
|
|
if (user.Role == Domain.UserRole.Normal)
|
|
{
|
|
// Normal user: only own devices
|
|
query = query.Where(d => d.UserId == user.Id);
|
|
}
|
|
else if (user.Role == Domain.UserRole.Supervisor)
|
|
{
|
|
// Supervisor: devices assigned to them
|
|
query = query.Where(d => d.DeviceUsers.Any(du => du.UserId == user.Id));
|
|
}
|
|
// Admin: all devices (no filter)
|
|
|
|
// Apply search filter
|
|
if (!string.IsNullOrWhiteSpace(filter.Search))
|
|
{
|
|
var searchTerm = filter.Search.Trim().ToLower();
|
|
query = query.Where(d =>
|
|
d.DeviceName.ToLower().Contains(searchTerm) ||
|
|
d.User.Name.ToLower().Contains(searchTerm) ||
|
|
d.User.Family.ToLower().Contains(searchTerm) ||
|
|
d.Location.ToLower().Contains(searchTerm));
|
|
}
|
|
|
|
// Get total count
|
|
var totalCount = await query.CountAsync(cancellationToken);
|
|
|
|
// Apply pagination
|
|
var items = await query
|
|
.OrderBy(d => d.DeviceName)
|
|
.Skip((filter.Page - 1) * filter.PageSize)
|
|
.Take(filter.PageSize)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
return new PagedResult<DeviceDto>
|
|
{
|
|
Items = mapper.Map<IReadOnlyList<DeviceDto>>(items),
|
|
TotalCount = totalCount,
|
|
Page = filter.Page,
|
|
PageSize = filter.PageSize
|
|
};
|
|
}
|
|
}
|