using Microsoft.AspNetCore.Mvc; namespace DRS9.Dashboard.Server.Controllers; [ApiController] [Route("api/admin/[controller]")] // [Authorize] - 暂时禁用认证以便测试 public class UploadController : ControllerBase { private readonly IWebHostEnvironment _environment; private readonly ILogger _logger; // 允许的图片扩展名 private static readonly string[] ImageExtensions = { ".png", ".jpg", ".jpeg", ".gif", ".bmp", ".svg", ".webp" }; // 允许的视频扩展名 private static readonly string[] VideoExtensions = { ".mp4", ".webm", ".ogg", ".mov", ".avi", ".mkv" }; // 最大文件大小 (50MB) private const long MaxFileSize = 50 * 1024 * 1024; public UploadController(IWebHostEnvironment environment, ILogger logger) { _environment = environment; _logger = logger; } /// /// 上传文件(图片或视频) /// [HttpPost] public async Task> UploadFile(IFormFile file) { if (file == null || file.Length == 0) { return BadRequest(new { success = false, message = "请选择文件" }); } // 检查文件大小 if (file.Length > MaxFileSize) { return BadRequest(new { success = false, message = $"文件大小不能超过 {MaxFileSize / 1024 / 1024}MB" }); } var extension = Path.GetExtension(file.FileName).ToLowerInvariant(); // 确定文件类型 string itemType; string subFolder; if (ImageExtensions.Contains(extension)) { itemType = "Image"; subFolder = "images"; } else if (VideoExtensions.Contains(extension)) { itemType = "Video"; subFolder = "videos"; } else { return BadRequest(new { success = false, message = "不支持的文件类型,请上传图片或视频" }); } try { // 创建上传目录 var uploadsFolder = Path.Combine(_environment.WebRootPath, "uploads", subFolder); if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } // 生成唯一文件名 var uniqueFileName = $"{Guid.NewGuid()}{extension}"; var filePath = Path.Combine(uploadsFolder, uniqueFileName); // 保存文件 using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } // 返回文件 URL var fileUrl = $"/uploads/{subFolder}/{uniqueFileName}"; _logger.LogInformation("文件上传成功: {FileName} -> {Url}", file.FileName, fileUrl); return Ok(new { success = true, message = "上传成功", url = fileUrl, itemType = itemType, fileName = file.FileName }); } catch (Exception ex) { _logger.LogError(ex, "文件上传失败"); return StatusCode(500, new { success = false, message = $"上传失败: {ex.Message}" }); } } /// /// 批量上传文件 /// [HttpPost("batch")] public async Task> UploadFiles(List files) { if (files == null || files.Count == 0) { return BadRequest(new { success = false, message = "请选择文件" }); } var results = new List(); var successCount = 0; var failCount = 0; foreach (var file in files) { var result = await UploadSingleFile(file); if (result.success) { successCount++; } else { failCount++; } results.Add(new { fileName = file.FileName, success = result.success, message = result.message, url = result.url, itemType = result.itemType }); } return Ok(new { success = true, message = $"上传完成: {successCount} 个成功, {failCount} 个失败", results = results }); } private async Task<(bool success, string message, string? url, string? itemType)> UploadSingleFile(IFormFile file) { if (file == null || file.Length == 0) { return (false, "请选择文件", null, null); } if (file.Length > MaxFileSize) { return (false, $"文件大小不能超过 {MaxFileSize / 1024 / 1024}MB", null, null); } var extension = Path.GetExtension(file.FileName).ToLowerInvariant(); string itemType; string subFolder; if (ImageExtensions.Contains(extension)) { itemType = "Image"; subFolder = "images"; } else if (VideoExtensions.Contains(extension)) { itemType = "Video"; subFolder = "videos"; } else { return (false, "不支持的文件类型", null, null); } try { var uploadsFolder = Path.Combine(_environment.WebRootPath, "uploads", subFolder); if (!Directory.Exists(uploadsFolder)) { Directory.CreateDirectory(uploadsFolder); } var uniqueFileName = $"{Guid.NewGuid()}{extension}"; var filePath = Path.Combine(uploadsFolder, uniqueFileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } var fileUrl = $"/uploads/{subFolder}/{uniqueFileName}"; return (true, "上传成功", fileUrl, itemType); } catch (Exception ex) { _logger.LogError(ex, "文件上传失败: {FileName}", file.FileName); return (false, $"上传失败: {ex.Message}", null, null); } } /// /// 删除文件 /// [HttpDelete] public ActionResult DeleteFile([FromBody] FileDeleteRequest request) { if (string.IsNullOrWhiteSpace(request.Url)) { return BadRequest(new { success = false, message = "请提供文件 URL" }); } try { // 从 URL 中提取文件路径 var filePath = Path.Combine(_environment.WebRootPath, request.Url.TrimStart('/')); if (System.IO.File.Exists(filePath)) { System.IO.File.Delete(filePath); _logger.LogInformation("文件删除成功: {Url}", request.Url); return Ok(new { success = true, message = "删除成功" }); } else { return NotFound(new { success = false, message = "文件不存在" }); } } catch (Exception ex) { _logger.LogError(ex, "文件删除失败: {Url}", request.Url); return StatusCode(500, new { success = false, message = $"删除失败: {ex.Message}" }); } } } public class FileDeleteRequest { public string Url { get; set; } = string.Empty; }