Dosya Yöneticisi gerçek zamanlı çalışıyor

This commit is contained in:
Sedat Öztürk 2025-10-26 11:32:35 +03:00
parent fc7e143e4e
commit c93007cc07
2 changed files with 77 additions and 69 deletions

View file

@ -9,6 +9,8 @@ using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kurs.Platform.BlobStoring; using Kurs.Platform.BlobStoring;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.MultiTenancy; using Volo.Abp.MultiTenancy;
@ -19,6 +21,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
{ {
private readonly ICurrentTenant _currentTenant; private readonly ICurrentTenant _currentTenant;
private readonly BlobManager _blobContainer; private readonly BlobManager _blobContainer;
private readonly IConfiguration _configuration;
private const string FileMetadataSuffix = ".metadata.json"; private const string FileMetadataSuffix = ".metadata.json";
private const string FolderMarkerSuffix = ".folder"; private const string FolderMarkerSuffix = ".folder";
@ -26,11 +29,13 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
public FileManagementAppService( public FileManagementAppService(
ICurrentTenant currentTenant, ICurrentTenant currentTenant,
BlobManager blobContainer BlobManager blobContainer,
IConfiguration configuration
) )
{ {
_currentTenant = currentTenant; _currentTenant = currentTenant;
_blobContainer = blobContainer; _blobContainer = blobContainer;
_configuration = configuration;
} }
private string GetTenantPrefix() private string GetTenantPrefix()
@ -46,68 +51,85 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
private async Task<List<FileMetadata>> GetFolderIndexAsync(string? parentId = null) private async Task<List<FileMetadata>> GetFolderIndexAsync(string? parentId = null)
{ {
// Root seviyesinde default klasörleri göster return await GetRealCdnContentsAsync(parentId);
if (string.IsNullOrEmpty(parentId)) }
private async Task<List<FileMetadata>> GetRealCdnContentsAsync(string? folderPath)
{
var items = new List<FileMetadata>();
var cdnBasePath = _configuration["App:CdnPath"];
if (string.IsNullOrEmpty(cdnBasePath))
{ {
var defaultFolders = new List<FileMetadata> Logger.LogWarning("CDN path is not configured");
{ return items;
// Default system folders
new() {
Id = BlobContainerNames.Avatar,
Name = "Avatar",
Type = "folder",
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow,
Path = BlobContainerNames.Avatar,
ParentId = "",
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
},
new() {
Id = BlobContainerNames.Import,
Name = "Import",
Type = "folder",
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow,
Path = BlobContainerNames.Import,
ParentId = "",
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
},
new() {
Id = BlobContainerNames.Activity,
Name = "Activity",
Type = "folder",
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow,
Path = BlobContainerNames.Activity,
ParentId = "",
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
}
};
// Custom folders from index
var customFolders = await GetCustomFoldersAsync();
defaultFolders.AddRange(customFolders);
return defaultFolders;
} }
// Alt klasörlerin indexini oku var tenantId = _currentTenant.Id?.ToString() ?? "host";
var indexPath = GetTenantPrefix() + $"{parentId}/{IndexFileName}"; var fullPath = Path.Combine(cdnBasePath, tenantId);
if (!string.IsNullOrEmpty(folderPath))
{
fullPath = Path.Combine(fullPath, folderPath);
}
try try
{ {
var indexBytes = await _blobContainer.GetAllBytesOrNullAsync(indexPath); if (!Directory.Exists(fullPath))
if (indexBytes == null) return new List<FileMetadata>(); {
Logger.LogWarning($"Directory does not exist: {fullPath}");
return items;
}
var indexJson = Encoding.UTF8.GetString(indexBytes); // Klasörleri listele
return JsonSerializer.Deserialize<List<FileMetadata>>(indexJson) ?? new List<FileMetadata>(); var directories = Directory.GetDirectories(fullPath);
foreach (var dir in directories)
{
var dirInfo = new DirectoryInfo(dir);
var relativePath = string.IsNullOrEmpty(folderPath) ? dirInfo.Name : $"{folderPath}/{dirInfo.Name}";
items.Add(new FileMetadata
{
Id = relativePath,
Name = dirInfo.Name,
Type = "folder",
CreatedAt = dirInfo.CreationTime,
ModifiedAt = dirInfo.LastWriteTime,
Path = relativePath,
ParentId = folderPath ?? "",
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
});
}
// Dosyaları listele
var files = Directory.GetFiles(fullPath);
foreach (var file in files)
{
var fileInfo = new FileInfo(file);
var relativePath = string.IsNullOrEmpty(folderPath) ? fileInfo.Name : $"{folderPath}/{fileInfo.Name}";
items.Add(new FileMetadata
{
Id = relativePath,
Name = fileInfo.Name,
Type = "file",
Size = fileInfo.Length,
CreatedAt = fileInfo.CreationTime,
ModifiedAt = fileInfo.LastWriteTime,
Path = relativePath,
ParentId = folderPath ?? "",
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
});
}
return items.OrderBy(x => x.Type == "folder" ? 0 : 1).ThenBy(x => x.Name).ToList();
} }
catch catch (Exception ex)
{ {
return new List<FileMetadata>(); Logger.LogError(ex, $"Error reading CDN contents from: {fullPath}");
return items;
} }
} }
@ -555,7 +577,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
private async Task<List<FileMetadata>> GetAllItemsRecursivelyAsync(string? parentId = null, List<FileMetadata>? result = null) private async Task<List<FileMetadata>> GetAllItemsRecursivelyAsync(string? parentId = null, List<FileMetadata>? result = null)
{ {
result ??= new List<FileMetadata>(); result ??= [];
var items = await GetFolderIndexAsync(parentId); var items = await GetFolderIndexAsync(parentId);
result.AddRange(items); result.AddRange(items);

View file

@ -269,11 +269,6 @@ const FileManager = () => {
setDeleteModalOpen(true) setDeleteModalOpen(true)
} }
const handleDeleteSelected = () => {
const itemsToDelete = items.filter((item) => selectedItems.includes(item.id))
openDeleteModal(itemsToDelete)
}
const goUpOneLevel = () => { const goUpOneLevel = () => {
if (breadcrumbItems.length > 1) { if (breadcrumbItems.length > 1) {
const parentBreadcrumb = breadcrumbItems[breadcrumbItems.length - 2] const parentBreadcrumb = breadcrumbItems[breadcrumbItems.length - 2]
@ -311,15 +306,6 @@ const FileManager = () => {
Go Up Go Up
</Button> </Button>
)} )}
{selectedItems.length > 0 && (
<Button
variant="solid"
className="bg-red-600 hover:bg-red-700 text-white"
onClick={handleDeleteSelected}
>
Delete Selected ({selectedItems.length})
</Button>
)}
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">