initial commit

This commit is contained in:
2026-07-21 14:35:37 +07:00
commit 0027997ff9
798 changed files with 59083 additions and 0 deletions
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.File.Avatar;
public class AvatarStorageModel
{
public bool IsUsed { get; set; }
public string StoragePath { get; set; } = "wwwroot/avatars";
public string BaseUrl { get; set; } = string.Empty;
}
@@ -0,0 +1,9 @@
namespace Indotalent.Infrastructure.File.Aws;
public class AwsS3SettingsModel
{
public bool IsUsed { get; set; }
public string AccessKey { get; set; } = string.Empty;
public string SecretKey { get; set; } = string.Empty;
public string BucketName { get; set; } = string.Empty;
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.File.Azure;
public class AzureBlobSettingsModel
{
public bool IsUsed { get; set; }
public string ConnectionString { get; set; } = string.Empty;
public string ContainerName { get; set; } = string.Empty;
}
+13
View File
@@ -0,0 +1,13 @@
namespace Indotalent.Infrastructure.File;
public static class DI
{
public static IServiceCollection AddFileService(this IServiceCollection services)
{
services.AddScoped<FileStorageService>();
return services;
}
}
@@ -0,0 +1,7 @@
namespace Indotalent.Infrastructure.File.Dropbox;
public class DropboxSettingsModel
{
public bool IsUsed { get; set; }
public string AccessToken { get; set; } = string.Empty;
}
+107
View File
@@ -0,0 +1,107 @@
using Microsoft.Extensions.Options;
namespace Indotalent.Infrastructure.File;
public class FileStorageService
{
private readonly FileStorageSettingsModel _settings;
private readonly IWebHostEnvironment _environment;
private readonly string[] _allowedAvatarExtensions = { ".jpg", ".jpeg", ".png" };
private readonly string[] _allowedDocExtensions = { ".pdf", ".xls", ".xlsx", ".doc", ".docx", ".txt" };
public FileStorageService(IOptions<FileStorageSettingsModel> options, IWebHostEnvironment environment)
{
_settings = options.Value;
_environment = environment;
}
public FileStorageSettingsModel GetConfiguration() => _settings;
private string GetPhysicalPath(string subFolder)
{
return Path.Combine(_environment.ContentRootPath, "wwwroot", subFolder);
}
public async Task<string> SaveAvatarAsync(string userId, byte[] fileData, string extension)
{
var avatarSettings = _settings.Avatar;
if (!avatarSettings.IsUsed) throw new Exception("Avatar storage is disabled.");
var ext = extension.ToLower();
if (!_allowedAvatarExtensions.Contains(ext))
throw new Exception("Invalid image type. Only JPG, JPEG, and PNG are allowed.");
var folderPath = GetPhysicalPath(avatarSettings.StoragePath);
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
var fileName = $"{Guid.NewGuid()}{ext}";
var filePath = Path.Combine(folderPath, fileName);
await System.IO.File.WriteAllBytesAsync(filePath, fileData);
return fileName;
}
public void DeleteOldAvatar(string? fileName)
{
if (string.IsNullOrEmpty(fileName)) return;
try
{
var folderPath = GetPhysicalPath(_settings.Avatar.StoragePath);
var filePath = Path.Combine(folderPath, fileName);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
catch { }
}
public async Task<string> SaveFileAsync(byte[] fileData, string extension)
{
var localSettings = _settings.Local;
if (!localSettings.IsUsed) throw new Exception("Local file storage is disabled.");
var ext = extension.ToLower();
if (!_allowedDocExtensions.Contains(ext))
throw new Exception($"File type {ext} is not allowed.");
var folderPath = GetPhysicalPath(localSettings.StoragePath);
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
var fileName = $"{Guid.NewGuid()}{ext}";
var filePath = Path.Combine(folderPath, fileName);
await System.IO.File.WriteAllBytesAsync(filePath, fileData);
return fileName;
}
public void DeleteFile(string? fileName)
{
if (string.IsNullOrEmpty(fileName)) return;
try
{
var folderPath = GetPhysicalPath(_settings.Local.StoragePath);
var filePath = Path.Combine(folderPath, fileName);
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
}
catch { }
}
}
@@ -0,0 +1,18 @@
using Indotalent.Infrastructure.File.Avatar;
using Indotalent.Infrastructure.File.Aws;
using Indotalent.Infrastructure.File.Azure;
using Indotalent.Infrastructure.File.Dropbox;
using Indotalent.Infrastructure.File.Google;
using Indotalent.Infrastructure.File.Local;
namespace Indotalent.Infrastructure.File;
public class FileStorageSettingsModel
{
public AvatarStorageModel Avatar { get; set; } = new();
public LocalStorageModel Local { get; set; } = new();
public AwsS3SettingsModel AwsS3 { get; set; } = new();
public AzureBlobSettingsModel AzureBlob { get; set; } = new();
public GoogleCloudSettingsModel GoogleCloud { get; set; } = new();
public DropboxSettingsModel Dropbox { get; set; } = new();
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.File.Google;
public class GoogleCloudSettingsModel
{
public bool IsUsed { get; set; }
public string ProjectId { get; set; } = string.Empty;
public string BucketName { get; set; } = string.Empty;
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.File.Local;
public class LocalStorageModel
{
public bool IsUsed { get; set; }
public string StoragePath { get; set; } = "wwwroot/uploads";
public string BaseUrl { get; set; } = string.Empty;
}