version 3
This commit is contained in:
212
src/GreenHome.Api/Controllers/DevicePostsController.cs
Normal file
212
src/GreenHome.Api/Controllers/DevicePostsController.cs
Normal file
@@ -0,0 +1,212 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using GreenHome.Application;
|
||||
|
||||
namespace GreenHome.Api.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("api/[controller]")]
|
||||
public class DevicePostsController : ControllerBase
|
||||
{
|
||||
private readonly IDevicePostService _postService;
|
||||
private readonly ILogger<DevicePostsController> _logger;
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
|
||||
public DevicePostsController(
|
||||
IDevicePostService postService,
|
||||
ILogger<DevicePostsController> logger,
|
||||
IWebHostEnvironment environment)
|
||||
{
|
||||
_postService = postService;
|
||||
_logger = logger;
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// دریافت پستهای گروه مجازی دستگاه (تایملاین)
|
||||
/// </summary>
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PagedResult<DevicePostDto>>> GetPosts(
|
||||
[FromQuery] int deviceId,
|
||||
[FromQuery] int? authorUserId,
|
||||
[FromQuery] int page = 1,
|
||||
[FromQuery] int pageSize = 20,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var filter = new DevicePostFilter
|
||||
{
|
||||
DeviceId = deviceId,
|
||||
AuthorUserId = authorUserId,
|
||||
Page = page,
|
||||
PageSize = pageSize
|
||||
};
|
||||
|
||||
var result = await _postService.GetPostsAsync(filter, cancellationToken);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// دریافت جزئیات یک پست
|
||||
/// </summary>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<ActionResult<DevicePostDto>> GetPostById(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
var result = await _postService.GetPostByIdAsync(id, cancellationToken);
|
||||
if (result == null)
|
||||
{
|
||||
return NotFound(new { error = $"پست با شناسه {id} یافت نشد" });
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ایجاد پست جدید در گروه مجازی
|
||||
/// </summary>
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<int>> CreatePost(
|
||||
CreateDevicePostRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var id = await _postService.CreatePostAsync(request, cancellationToken);
|
||||
return Ok(new { id, message = "پست با موفقیت ایجاد شد" });
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
return Unauthorized(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ویرایش پست
|
||||
/// </summary>
|
||||
[HttpPut]
|
||||
public async Task<ActionResult> UpdatePost(
|
||||
UpdateDevicePostRequest request,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _postService.UpdatePostAsync(request, cancellationToken);
|
||||
return Ok(new { message = "پست با موفقیت ویرایش شد" });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return NotFound(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// حذف پست
|
||||
/// </summary>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task<ActionResult> DeletePost(int id, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _postService.DeletePostAsync(id, cancellationToken);
|
||||
return Ok(new { message = "پست با موفقیت حذف شد" });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return NotFound(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// آپلود تصویر برای پست
|
||||
/// </summary>
|
||||
[HttpPost("{postId}/images")]
|
||||
[Consumes("multipart/form-data")]
|
||||
public async Task<ActionResult<int>> UploadImage(
|
||||
int postId,
|
||||
[FromForm] IFormFile file,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (file == null || file.Length == 0)
|
||||
{
|
||||
return BadRequest(new { error = "فایل انتخاب نشده است" });
|
||||
}
|
||||
|
||||
// Validate file type
|
||||
var allowedTypes = new[] { "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp" };
|
||||
if (!allowedTypes.Contains(file.ContentType.ToLower()))
|
||||
{
|
||||
return BadRequest(new { error = "فقط فایلهای تصویری مجاز هستند" });
|
||||
}
|
||||
|
||||
// Validate file size (max 5MB)
|
||||
if (file.Length > 5 * 1024 * 1024)
|
||||
{
|
||||
return BadRequest(new { error = "حجم فایل نباید بیشتر از 5 مگابایت باشد" });
|
||||
}
|
||||
|
||||
// Create upload directory
|
||||
var uploadsFolder = Path.Combine(_environment.WebRootPath ?? "wwwroot", "uploads", "posts");
|
||||
Directory.CreateDirectory(uploadsFolder);
|
||||
|
||||
// Generate unique filename
|
||||
var fileName = $"{Guid.NewGuid()}_{Path.GetFileName(file.FileName)}";
|
||||
var filePath = Path.Combine(uploadsFolder, fileName);
|
||||
|
||||
// Save file
|
||||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
await file.CopyToAsync(stream, cancellationToken);
|
||||
}
|
||||
|
||||
// Save to database
|
||||
var relativePath = $"/uploads/posts/{fileName}";
|
||||
var imageId = await _postService.AddImageToPostAsync(
|
||||
postId,
|
||||
file.FileName,
|
||||
relativePath,
|
||||
file.ContentType,
|
||||
file.Length,
|
||||
cancellationToken);
|
||||
|
||||
_logger.LogInformation("Image uploaded for post {PostId}: {ImageId}", postId, imageId);
|
||||
|
||||
return Ok(new { imageId, filePath = relativePath, message = "تصویر با موفقیت آپلود شد" });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return NotFound(new { error = ex.Message });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error uploading image for post {PostId}", postId);
|
||||
return StatusCode(500, new { error = "خطا در آپلود تصویر" });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// حذف تصویر از پست
|
||||
/// </summary>
|
||||
[HttpDelete("images/{imageId}")]
|
||||
public async Task<ActionResult> DeleteImage(int imageId, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _postService.DeleteImageAsync(imageId, cancellationToken);
|
||||
return Ok(new { message = "تصویر با موفقیت حذف شد" });
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
return NotFound(new { error = ex.Message });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// بررسی دسترسی کاربر به دستگاه
|
||||
/// </summary>
|
||||
[HttpGet("access/{userId}/{deviceId}")]
|
||||
public async Task<ActionResult<bool>> CheckAccess(int userId, int deviceId, CancellationToken cancellationToken)
|
||||
{
|
||||
var hasAccess = await _postService.CanUserAccessDeviceAsync(userId, deviceId, cancellationToken);
|
||||
return Ok(new { hasAccess });
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user