version 3

This commit is contained in:
2025-12-17 00:34:41 +03:30
parent 139924db94
commit 74e8480a68
38 changed files with 5399 additions and 70 deletions

View File

@@ -0,0 +1,185 @@
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;
}
}