Files
yes.blog/Yes.Application/Admins/Themes/UploadThemeCommandHandler.cs
2025-05-16 23:14:52 +08:00

105 lines
3.7 KiB
C#

namespace Yes.Application.Admins.Themes
{
public record UploadThemeCommand(IFormFile File, string Theme) : IRequest<UploadThemeCommandResponse>;
public record UploadThemeCommandResponse(string DirName);
public class UploadThemeCommandHandler(
IWebHostEnvironment env,
BlogDbContext db,
IIdentityContext identity,
IOptionsMonitor<BlogSettings> options) : IRequestHandler<UploadThemeCommand, UploadThemeCommandResponse>
{
private readonly IWebHostEnvironment _env = env;
private readonly BlogSettings _settings = options.CurrentValue;
private readonly BlogDbContext _db = db;
private readonly IIdentityContext _identity = identity;
public async Task<UploadThemeCommandResponse> Handle(UploadThemeCommand request, CancellationToken cancellationToken)
{
var identityUser = await _db.Users.FindAsync(_identity.Id);
if (identityUser == null)
{
throw new UserNotExistsException(_identity.Id);
}
if (!identityUser.IsSystemUser())
{
throw new AccessDeniedException();
}
try
{
var file = request.File;
var theme = request.Theme;
if(string.IsNullOrWhiteSpace(theme))
{
theme = Guid.NewGuid().ToString().ToLower();
}
var ext = Path.GetExtension(file.FileName).ToLowerInvariant();
var allowedExts = _settings.AllowedUploadExts;
if (!ext.Equals(".zip"))
{
throw new FileTypeException(".zip");
}
if (file.Length > _settings.UploadSizeLimit)
{
throw new FileOverflowException($"{_settings.UploadSizeLimit / 1024 / 1024}M");
}
var baseUploadPath = "uploads";
var datePath = DateTime.Now.ToString("yyyyMM");
var uploads = Path.Combine(_env.ContentRootPath, "files", baseUploadPath, datePath);
if (!Directory.Exists(uploads))
{
Directory.CreateDirectory(uploads);
}
var hashKey = "";
using (var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
memoryStream.Position = 0;
using (var cryptoProvider = SHA256.Create())
{
byte[] hashBytes = cryptoProvider.ComputeHash(memoryStream);
hashKey = BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
}
}
var newFileName = $"{hashKey}{ext}";
var filePath = Path.Combine(uploads, newFileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var newDirName = Path.GetFileName(file.FileName).Replace(".zip", "");
var targetDirectory = Path.Combine(_env.ContentRootPath, "files", "themes");
ZipHelper.ExtractAndProcessZip(filePath, targetDirectory, theme);
return new UploadThemeCommandResponse(newDirName);
}
catch (Exception ex) when (ex is OverflowException)
{
throw new FileOverflowException();
}
catch (Exception ex) when (ex is InvalidDataException)
{
throw new FileNotSupportedException(ex.Message);
}
}
}
}