Dosya Yöneticis kısmında iç içe klasörler

This commit is contained in:
Sedat Öztürk 2025-10-26 12:27:06 +03:00
parent f839d1fec0
commit 79bd897a0b
2 changed files with 62 additions and 60 deletions

View file

@ -48,6 +48,18 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
return Guid.NewGuid().ToString("N");
}
private string EncodePathAsId(string path)
{
// Path'deki '/' karakterlerini '|' ile değiştir URL-safe hale getirmek için
return path.Replace("/", "|");
}
private string DecodeIdAsPath(string id)
{
// ID'deki '|' karakterlerini '/' ile geri değiştir
return id.Replace("|", "/");
}
private async Task<List<FileMetadata>> GetFolderIndexAsync(string? parentId = null)
{
return await GetRealCdnContentsAsync(parentId);
@ -89,7 +101,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
items.Add(new FileMetadata
{
Id = relativePath,
Id = EncodePathAsId(relativePath),
Name = dirInfo.Name,
Type = "folder",
CreatedAt = dirInfo.CreationTime,
@ -110,7 +122,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
items.Add(new FileMetadata
{
Id = relativePath,
Id = EncodePathAsId(relativePath),
Name = fileInfo.Name,
Type = "file",
Size = fileInfo.Length,
@ -170,7 +182,8 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
public async Task<GetFilesDto> GetItemsByParentAsync(string parentId)
{
return await GetItemsInternalAsync(parentId);
var decodedParentId = DecodeIdAsPath(parentId);
return await GetItemsInternalAsync(decodedParentId);
}
private async Task<GetFilesDto> GetItemsInternalAsync(string? parentId)
@ -208,9 +221,11 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
var tenantId = _currentTenant.Id?.ToString() ?? "host";
var parentPath = Path.Combine(cdnBasePath, tenantId);
string? decodedParentId = null;
if (!string.IsNullOrEmpty(input.ParentId))
{
parentPath = Path.Combine(parentPath, input.ParentId);
decodedParentId = DecodeIdAsPath(input.ParentId);
parentPath = Path.Combine(parentPath, decodedParentId);
}
var folderPath = Path.Combine(parentPath, input.Name);
@ -230,15 +245,17 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
// Klasörü oluştur
Directory.CreateDirectory(folderPath);
var newFolderPath = string.IsNullOrEmpty(decodedParentId) ? input.Name : $"{decodedParentId}/{input.Name}";
var metadata = new FileMetadata
{
Id = string.IsNullOrEmpty(input.ParentId) ? input.Name : $"{input.ParentId}/{input.Name}",
Id = EncodePathAsId(newFolderPath),
Name = input.Name,
Type = "folder",
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow,
Path = string.IsNullOrEmpty(input.ParentId) ? input.Name : $"{input.ParentId}/{input.Name}",
ParentId = input.ParentId ?? string.Empty,
Path = newFolderPath,
ParentId = decodedParentId ?? string.Empty,
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
};
@ -260,19 +277,25 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
{
ValidateFileName(input.FileName);
var items = await GetFolderIndexAsync(input.ParentId);
// Decode parent ID if provided
string? decodedParentId = null;
if (!string.IsNullOrEmpty(input.ParentId))
{
decodedParentId = DecodeIdAsPath(input.ParentId);
}
var items = await GetFolderIndexAsync(decodedParentId);
if (items.Any(x => x.Name.Equals(input.FileName, StringComparison.OrdinalIgnoreCase)))
{
throw new UserFriendlyException("A file with this name already exists");
}
var fileId = GenerateFileId();
var filePath = string.IsNullOrEmpty(input.ParentId)
var filePath = string.IsNullOrEmpty(decodedParentId)
? input.FileName
: $"{input.ParentId}/{input.FileName}";
: $"{decodedParentId}/{input.FileName}";
var blobPath = GetTenantPrefix() + filePath;
var fileId = EncodePathAsId(filePath);
// Save file content to CDN path
var cdnBasePath = _configuration["App:CdnPath"];
@ -284,9 +307,9 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
var tenantId = _currentTenant.Id?.ToString() ?? "host";
var fullCdnPath = Path.Combine(cdnBasePath, tenantId);
if (!string.IsNullOrEmpty(input.ParentId))
if (!string.IsNullOrEmpty(decodedParentId))
{
fullCdnPath = Path.Combine(fullCdnPath, input.ParentId);
fullCdnPath = Path.Combine(fullCdnPath, decodedParentId);
}
// Dizini oluştur
@ -325,14 +348,12 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow,
Path = filePath,
ParentId = input.ParentId ?? string.Empty,
ParentId = decodedParentId ?? string.Empty,
IsReadOnly = false,
TenantId = _currentTenant.Id?.ToString()
};
// Update parent index
items.Add(metadata);
await SaveFolderIndexAsync(items, input.ParentId);
// File system'e kaydedildi, index güncellemeye gerek yok
return new FileItemDto
{
@ -485,7 +506,8 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
}
var tenantId = _currentTenant.Id?.ToString() ?? "host";
var fullPath = Path.Combine(cdnBasePath, tenantId, id);
var actualPath = DecodeIdAsPath(id);
var fullPath = Path.Combine(cdnBasePath, tenantId, actualPath);
if (Directory.Exists(fullPath))
{
@ -512,7 +534,8 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
}
var tenantId = _currentTenant.Id?.ToString() ?? "host";
var fullFilePath = Path.Combine(cdnBasePath, tenantId, id);
var actualPath = DecodeIdAsPath(id);
var fullFilePath = Path.Combine(cdnBasePath, tenantId, actualPath);
if (!File.Exists(fullFilePath))
{
@ -557,38 +580,7 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
public async Task<FolderPathDto> GetFolderPathAsync(string? folderId = null)
{
var path = new List<PathItemDto>();
if (string.IsNullOrEmpty(folderId))
{
return new FolderPathDto { Path = path };
}
var metadata = await FindItemMetadataAsync(folderId);
if (metadata == null || metadata.Type != "folder")
{
throw new UserFriendlyException("Folder not found");
}
var pathParts = metadata.Path.Split('/', StringSplitOptions.RemoveEmptyEntries);
var currentPath = "";
foreach (var part in pathParts)
{
currentPath = string.IsNullOrEmpty(currentPath) ? part : $"{currentPath}/{part}";
var folderMetadata = await FindItemByPathAsync(currentPath);
if (folderMetadata != null)
{
path.Add(new PathItemDto
{
Id = folderMetadata.Id,
Name = folderMetadata.Name
});
}
}
return new FolderPathDto { Path = path };
return await GetFolderPathInternalAsync(folderId);
}
#region Private Helper Methods
@ -698,21 +690,30 @@ public class FileManagementAppService : ApplicationService, IFileManagementAppSe
return new FolderPathDto { Path = pathItems };
}
// Reconstruct path from folderId
var currentPath = folderId;
var pathParts = currentPath.Split('/', StringSplitOptions.RemoveEmptyEntries);
// Decode the folderId to get the actual path
var decodedPath = DecodeIdAsPath(folderId);
Logger.LogInformation($"GetFolderPath - FolderId: {folderId}, DecodedPath: {decodedPath}");
var reconstructedPath = "";
foreach (var part in pathParts)
// Split path into parts and build breadcrumb
var pathParts = decodedPath.Split('/', StringSplitOptions.RemoveEmptyEntries);
var currentEncodedPath = "";
for (int i = 0; i < pathParts.Length; i++)
{
reconstructedPath = string.IsNullOrEmpty(reconstructedPath) ? part : $"{reconstructedPath}/{part}";
// Build the path up to current level
var pathUpToCurrent = string.Join("/", pathParts.Take(i + 1));
currentEncodedPath = EncodePathAsId(pathUpToCurrent);
Logger.LogInformation($"PathItem {i}: Name='{pathParts[i]}', Id='{currentEncodedPath}', PathUpToCurrent='{pathUpToCurrent}'");
pathItems.Add(new PathItemDto
{
Id = reconstructedPath,
Name = part
Id = currentEncodedPath,
Name = pathParts[i] // Use the actual folder name, not encoded path
});
}
Logger.LogInformation($"Returning {pathItems.Count} breadcrumb items");
return new FolderPathDto { Path = pathItems };
}

View file

@ -78,6 +78,7 @@ const FileManager = () => {
}
const response = await fileManagementService.getFolderPath(folderId)
console.log('Breadcrumb response for folderId:', folderId, response)
const pathItems: BreadcrumbItem[] = [
{ name: 'Files', path: '', id: undefined },
...response.data.path.map((item) => ({