186 lines
5.6 KiB
C#
186 lines
5.6 KiB
C#
using AutoMapper;
|
|
using GreenHome.Application;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace GreenHome.Infrastructure;
|
|
|
|
public sealed class DevicePostService : IDevicePostService
|
|
{
|
|
private readonly GreenHomeDbContext _context;
|
|
private readonly IMapper _mapper;
|
|
|
|
public DevicePostService(GreenHomeDbContext context, IMapper mapper)
|
|
{
|
|
_context = context;
|
|
_mapper = mapper;
|
|
}
|
|
|
|
public async Task<PagedResult<DevicePostDto>> GetPostsAsync(
|
|
DevicePostFilter filter,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var query = _context.DevicePosts
|
|
.Include(p => p.AuthorUser)
|
|
.Include(p => p.Images)
|
|
.AsNoTracking()
|
|
.Where(p => p.DeviceId == filter.DeviceId);
|
|
|
|
if (filter.AuthorUserId.HasValue)
|
|
{
|
|
query = query.Where(p => p.AuthorUserId == filter.AuthorUserId.Value);
|
|
}
|
|
|
|
var totalCount = await query.CountAsync(cancellationToken);
|
|
|
|
var posts = await query
|
|
.OrderByDescending(p => p.CreatedAt)
|
|
.Skip((filter.Page - 1) * filter.PageSize)
|
|
.Take(filter.PageSize)
|
|
.ToListAsync(cancellationToken);
|
|
|
|
var dtos = _mapper.Map<List<DevicePostDto>>(posts);
|
|
|
|
return new PagedResult<DevicePostDto>
|
|
{
|
|
Items = dtos,
|
|
TotalCount = totalCount,
|
|
Page = filter.Page,
|
|
PageSize = filter.PageSize
|
|
};
|
|
}
|
|
|
|
public async Task<DevicePostDto?> GetPostByIdAsync(int id, CancellationToken cancellationToken)
|
|
{
|
|
var post = await _context.DevicePosts
|
|
.Include(p => p.AuthorUser)
|
|
.Include(p => p.Images)
|
|
.AsNoTracking()
|
|
.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
|
|
|
|
return post != null ? _mapper.Map<DevicePostDto>(post) : null;
|
|
}
|
|
|
|
public async Task<int> CreatePostAsync(
|
|
CreateDevicePostRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
// Verify user has access to device
|
|
var hasAccess = await CanUserAccessDeviceAsync(request.AuthorUserId, request.DeviceId, cancellationToken);
|
|
if (!hasAccess)
|
|
{
|
|
throw new UnauthorizedAccessException("کاربر به این دستگاه دسترسی ندارد");
|
|
}
|
|
|
|
var post = new Domain.DevicePost
|
|
{
|
|
DeviceId = request.DeviceId,
|
|
AuthorUserId = request.AuthorUserId,
|
|
Content = request.Content,
|
|
CreatedAt = DateTime.UtcNow
|
|
};
|
|
|
|
_context.DevicePosts.Add(post);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
return post.Id;
|
|
}
|
|
|
|
public async Task UpdatePostAsync(
|
|
UpdateDevicePostRequest request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var post = await _context.DevicePosts
|
|
.FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);
|
|
|
|
if (post == null)
|
|
{
|
|
throw new InvalidOperationException($"پست با شناسه {request.Id} یافت نشد");
|
|
}
|
|
|
|
post.Content = request.Content;
|
|
post.UpdatedAt = DateTime.UtcNow;
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
|
|
public async Task DeletePostAsync(int id, CancellationToken cancellationToken)
|
|
{
|
|
var post = await _context.DevicePosts
|
|
.Include(p => p.Images)
|
|
.FirstOrDefaultAsync(p => p.Id == id, cancellationToken);
|
|
|
|
if (post == null)
|
|
{
|
|
throw new InvalidOperationException($"پست با شناسه {id} یافت نشد");
|
|
}
|
|
|
|
_context.DevicePosts.Remove(post);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
|
|
public async Task<int> AddImageToPostAsync(
|
|
int postId,
|
|
string fileName,
|
|
string filePath,
|
|
string contentType,
|
|
long fileSize,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
var post = await _context.DevicePosts
|
|
.FirstOrDefaultAsync(p => p.Id == postId, cancellationToken);
|
|
|
|
if (post == null)
|
|
{
|
|
throw new InvalidOperationException($"پست با شناسه {postId} یافت نشد");
|
|
}
|
|
|
|
var image = new Domain.DevicePostImage
|
|
{
|
|
DevicePostId = postId,
|
|
FileName = fileName,
|
|
FilePath = filePath,
|
|
ContentType = contentType,
|
|
FileSize = fileSize,
|
|
UploadedAt = DateTime.UtcNow
|
|
};
|
|
|
|
_context.DevicePostImages.Add(image);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
return image.Id;
|
|
}
|
|
|
|
public async Task DeleteImageAsync(int imageId, CancellationToken cancellationToken)
|
|
{
|
|
var image = await _context.DevicePostImages
|
|
.FirstOrDefaultAsync(i => i.Id == imageId, cancellationToken);
|
|
|
|
if (image == null)
|
|
{
|
|
throw new InvalidOperationException($"تصویر با شناسه {imageId} یافت نشد");
|
|
}
|
|
|
|
_context.DevicePostImages.Remove(image);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
|
|
public async Task<bool> CanUserAccessDeviceAsync(
|
|
int userId,
|
|
int deviceId,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
// Check if user is the device owner or has access through DeviceUsers
|
|
var hasAccess = await _context.Devices
|
|
.AnyAsync(d => d.Id == deviceId && d.UserId == userId, cancellationToken);
|
|
|
|
if (!hasAccess)
|
|
{
|
|
hasAccess = await _context.DeviceUsers
|
|
.AnyAsync(du => du.DeviceId == deviceId && du.UserId == userId, cancellationToken);
|
|
}
|
|
|
|
return hasAccess;
|
|
}
|
|
}
|
|
|