This commit is contained in:
gpu 2026-02-02 11:15:51 +08:00
parent 81fb507fab
commit a1f6d3bc4e

View File

@ -1,178 +0,0 @@
using HoneyBox.Core.Interfaces;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace HoneyBox.Admin.Controllers;
/// <summary>
/// 文件上传控制器
/// </summary>
[ApiController]
[Route("api/admin/upload")]
[Authorize]
public class UploadController : ControllerBase
{
private readonly IImageUploadService _uploadService;
private readonly ILogger<UploadController> _logger;
private static readonly HashSet<string> AllowedImageExtensions = new(StringComparer.OrdinalIgnoreCase)
{
".jpg", ".jpeg", ".png", ".gif", ".webp", ".avif"
};
private const long MaxFileSize = 20 * 1024 * 1024; // 20MB
public UploadController(IImageUploadService uploadService, ILogger<UploadController> logger)
{
_uploadService = uploadService;
_logger = logger;
}
/// <summary>
/// 获取预签名上传URL当前不支持直传返回标识让前端降级
/// </summary>
[HttpPost("presigned-url")]
public IActionResult GetPresignedUrl([FromBody] PresignedUrlRequest request)
{
// 当前不支持直传,返回标识让前端降级到服务端上传
return Ok(new
{
code = 0,
message = "success",
data = new { supportsDirectUpload = false }
});
}
/// <summary>
/// 上传图片(服务端上传)
/// </summary>
[HttpPost("image")]
[RequestSizeLimit(MaxFileSize)]
public async Task<IActionResult> UploadImage(IFormFile file)
{
if (file == null || file.Length == 0)
{
return Ok(new { code = 1, message = "请选择要上传的图片" });
}
if (file.Length > MaxFileSize)
{
return Ok(new { code = 1, message = "图片大小不能超过20MB" });
}
var extension = Path.GetExtension(file.FileName);
if (!AllowedImageExtensions.Contains(extension))
{
return Ok(new { code = 1, message = "不支持的图片格式,仅支持 jpg/jpeg/png/gif/webp/avif" });
}
try
{
using var stream = file.OpenReadStream();
var url = await _uploadService.UploadStreamAsync(stream, file.FileName, file.ContentType, "uploads");
if (!string.IsNullOrEmpty(url))
{
return Ok(new
{
code = 0,
message = "上传成功",
data = new
{
url,
fileName = file.FileName,
fileSize = file.Length
}
});
}
else
{
return Ok(new { code = 1, message = "上传失败" });
}
}
catch (Exception ex)
{
_logger.LogError(ex, "图片上传异常: {FileName}", file.FileName);
return Ok(new { code = 1, message = "上传失败,请稍后重试" });
}
}
/// <summary>
/// 批量上传图片
/// </summary>
[HttpPost("images")]
[RequestSizeLimit(MaxFileSize * 10)]
public async Task<IActionResult> UploadImages(List<IFormFile> files)
{
if (files == null || files.Count == 0)
{
return Ok(new { code = 1, message = "请选择要上传的图片" });
}
var results = new List<object>();
var errors = new List<string>();
foreach (var file in files)
{
if (file.Length > MaxFileSize)
{
errors.Add($"{file.FileName}: 文件大小超过限制");
continue;
}
var extension = Path.GetExtension(file.FileName);
if (!AllowedImageExtensions.Contains(extension))
{
errors.Add($"{file.FileName}: 不支持的图片格式");
continue;
}
try
{
using var stream = file.OpenReadStream();
var url = await _uploadService.UploadStreamAsync(stream, file.FileName, file.ContentType, "uploads");
if (!string.IsNullOrEmpty(url))
{
results.Add(new
{
url,
fileName = file.FileName,
fileSize = file.Length
});
}
else
{
errors.Add($"{file.FileName}: 上传失败");
}
}
catch (Exception ex)
{
_logger.LogError(ex, "图片上传异常: {FileName}", file.FileName);
errors.Add($"{file.FileName}: 上传异常");
}
}
if (results.Count == 0)
{
return Ok(new { code = 1, message = string.Join("; ", errors) });
}
return Ok(new
{
code = 0,
message = errors.Count > 0 ? $"部分上传成功,失败: {string.Join("; ", errors)}" : "上传成功",
data = results
});
}
}
/// <summary>
/// 预签名URL请求
/// </summary>
public class PresignedUrlRequest
{
public string FileName { get; set; } = string.Empty;
public string ContentType { get; set; } = string.Empty;
public long FileSize { get; set; }
}