108 lines
3.6 KiB
C#
108 lines
3.6 KiB
C#
using GozareshgirProgramManager.Application.Services.FileManagement;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.Hosting;
|
|
|
|
namespace GozareshgirProgramManager.Infrastructure.Services.FileManagement;
|
|
|
|
/// <summary>
|
|
/// سرویس ذخیرهسازی فایل در سیستم فایل محلی
|
|
/// </summary>
|
|
public class LocalFileStorageService : IFileStorageService
|
|
{
|
|
private readonly string _uploadBasePath;
|
|
private readonly string _baseUrl;
|
|
|
|
public LocalFileStorageService(IConfiguration configuration,
|
|
IHttpContextAccessor httpContextAccessor, IHostEnvironment env)
|
|
{
|
|
// محاسبه مسیر پایه: اگر env نبود، از مسیر فعلی استفاده کن
|
|
var contentRoot = env.ContentRootPath;
|
|
_uploadBasePath = Path.Combine(contentRoot, "Storage");
|
|
// Base URL برای دسترسی به فایلها
|
|
var request = httpContextAccessor.HttpContext?.Request;
|
|
if (request != null)
|
|
{
|
|
_baseUrl = $"{request.Scheme}://{request.Host}/uploads";
|
|
}
|
|
else
|
|
{
|
|
_baseUrl = configuration["FileStorage:BaseUrl"] ?? "http://localhost:5000/uploads";
|
|
}
|
|
|
|
// ایجاد پوشه اگر وجود نداشت
|
|
if (!Directory.Exists(_uploadBasePath))
|
|
{
|
|
Directory.CreateDirectory(_uploadBasePath);
|
|
}
|
|
}
|
|
|
|
public async Task<(string StoragePath, string StorageUrl)> UploadAsync(
|
|
Stream fileStream,
|
|
string uniqueFileName,
|
|
string category)
|
|
{
|
|
// ایجاد پوشه دستهبندی (مثلاً: Uploads/TaskChatMessage)
|
|
var categoryPath = Path.Combine(_uploadBasePath, category);
|
|
if (!Directory.Exists(categoryPath))
|
|
{
|
|
Directory.CreateDirectory(categoryPath);
|
|
}
|
|
|
|
// ایجاد زیرپوشه بر اساس تاریخ (مثلاً: Uploads/TaskChatMessage/2026/01)
|
|
var datePath = Path.Combine(categoryPath, DateTime.Now.Year.ToString(),
|
|
DateTime.Now.Month.ToString("00"));
|
|
if (!Directory.Exists(datePath))
|
|
{
|
|
Directory.CreateDirectory(datePath);
|
|
}
|
|
|
|
// مسیر کامل فایل
|
|
var storagePath = Path.Combine(datePath, uniqueFileName);
|
|
|
|
// ذخیره فایل
|
|
await using var fileStreamOutput = new FileStream(storagePath, FileMode.Create, FileAccess.Write);
|
|
await fileStream.CopyToAsync(fileStreamOutput);
|
|
|
|
// URL فایل
|
|
var relativePath = Path.GetRelativePath(_uploadBasePath, storagePath)
|
|
.Replace("\\", "/");
|
|
var storageUrl = $"{_baseUrl}/{relativePath}";
|
|
|
|
return (storagePath, storageUrl);
|
|
}
|
|
|
|
public Task DeleteAsync(string storagePath)
|
|
{
|
|
if (File.Exists(storagePath))
|
|
{
|
|
File.Delete(storagePath);
|
|
}
|
|
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
public Task<Stream?> GetFileStreamAsync(string storagePath)
|
|
{
|
|
if (!File.Exists(storagePath))
|
|
{
|
|
return Task.FromResult<Stream?>(null);
|
|
}
|
|
|
|
var stream = new FileStream(storagePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
return Task.FromResult<Stream?>(stream);
|
|
}
|
|
|
|
public Task<bool> ExistsAsync(string storagePath)
|
|
{
|
|
return Task.FromResult(File.Exists(storagePath));
|
|
}
|
|
|
|
public string GetFileUrl(string storagePath)
|
|
{
|
|
var relativePath = Path.GetRelativePath(_uploadBasePath, storagePath)
|
|
.Replace("\\", "/");
|
|
return $"{_baseUrl}/{relativePath}";
|
|
}
|
|
}
|