237 lines
8.8 KiB
C#
237 lines
8.8 KiB
C#
using Apimanager_backend.Exceptions;
|
||
using Apimanager_backend.Services;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using SixLabors.ImageSharp; // 确保添加这个using
|
||
using SixLabors.ImageSharp.Processing;
|
||
using SixLabors.ImageSharp.Formats.Jpeg;
|
||
using SixLabors.ImageSharp.Formats.Png;
|
||
using Apimanager_backend.Dtos;
|
||
|
||
namespace Apimanager_backend.Controllers
|
||
{
|
||
[ApiController]
|
||
[Route("api/[controller]/[action]")]
|
||
public class UploadController:ControllerBase
|
||
{
|
||
private ILogger<UploadController> _logger;
|
||
private readonly IWebHostEnvironment _environment;
|
||
private IUserService _userService;
|
||
|
||
// 最大文件大小 5MB
|
||
private const long MaxFileSize = 5 * 1024 * 1024;
|
||
// 允许的文件类型
|
||
private static readonly string[] AllowedExtensions = { ".jpg", ".jpeg", ".png", ".gif" };
|
||
public UploadController(ILogger<UploadController> logger,IWebHostEnvironment webHostEnvironment,IUserService userService)
|
||
{
|
||
_logger = logger;
|
||
_environment = webHostEnvironment;
|
||
_userService = userService;
|
||
}
|
||
[HttpPost]
|
||
[Authorize(Roles = "User")]
|
||
public async Task<IActionResult> UploadPic(IFormFile file)
|
||
{
|
||
try
|
||
{
|
||
// 1. 验证文件
|
||
if (file == null || file.Length == 0)
|
||
{
|
||
throw new BaseException(1001,"缺少文件");
|
||
}
|
||
|
||
// 2. 验证文件大小
|
||
if (file.Length > MaxFileSize)
|
||
{
|
||
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
|
||
}
|
||
|
||
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
|
||
// 3. 验证文件类型
|
||
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
|
||
if (string.IsNullOrEmpty(extension) || !AllowedExtensions.Contains(extension))
|
||
{
|
||
throw new BaseException(1001, "只支持 JPG, PNG, GIF 格式的图片");
|
||
}
|
||
|
||
|
||
// 5. 创建存储目录
|
||
var uploadsFolder = Path.Combine(basePath, "uploads", "avatars");
|
||
if (!Directory.Exists(uploadsFolder))
|
||
{
|
||
Directory.CreateDirectory(uploadsFolder);
|
||
}
|
||
var userId = User.Claims.First(x => x.Type == "userId").Value;
|
||
|
||
// 6. 生成唯一文件名
|
||
var uniqueFileName = $"{userId}_{DateTime.Now:yyyyMMddHHmmss}{extension}";
|
||
var filePath = Path.Combine(uploadsFolder, uniqueFileName);
|
||
|
||
// 7. 处理并保存图片
|
||
using (var image = await Image.LoadAsync(file.OpenReadStream()))
|
||
{
|
||
// 调整图片大小(最大200x200)
|
||
image.Mutate(x => x.Resize(new ResizeOptions
|
||
{
|
||
Size = new Size(200, 200),
|
||
Mode = ResizeMode.Max
|
||
}));
|
||
|
||
// 保存为高质量JPEG
|
||
await image.SaveAsync(filePath);
|
||
}
|
||
|
||
// 8. 更新数据库中的头像路径
|
||
var avatarUrl = $"/uploads/avatars/{uniqueFileName}";
|
||
var result = await _userService.UpdateUserAvatarAsync(int.Parse(userId), avatarUrl);
|
||
|
||
if (!result)
|
||
{
|
||
// 如果数据库更新失败,删除已上传的文件
|
||
System.IO.File.Delete(filePath);
|
||
throw new BaseException(1004,"头像上传失败");
|
||
}
|
||
|
||
// 9. 返回成功响应
|
||
return Ok(new ResponseBase<object>(1000,"头像上传成功",null));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "头像上传失败");
|
||
throw new BaseException(1004, "头像上传失败");
|
||
}
|
||
}
|
||
[HttpPost]
|
||
[Authorize(Roles = "Admin")]
|
||
public async Task<IActionResult> UploadLogo(IFormFile file)
|
||
{
|
||
try
|
||
{
|
||
// 1. 验证文件
|
||
if (file == null || file.Length == 0)
|
||
{
|
||
throw new BaseException(1001, "缺少文件");
|
||
}
|
||
|
||
// 2. 验证文件大小
|
||
if (file.Length > MaxFileSize)
|
||
{
|
||
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
|
||
}
|
||
|
||
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
|
||
// 3. 验证文件类型
|
||
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
|
||
if (string.IsNullOrEmpty(extension) || !AllowedExtensions.Contains(extension))
|
||
{
|
||
throw new BaseException(1001, "只支持 JPG, PNG, GIF 格式的图片");
|
||
}
|
||
|
||
|
||
// 5. 创建存储目录
|
||
var uploadsFolder = Path.Combine(basePath);
|
||
var filePath = Path.Combine(uploadsFolder, "logo.png");
|
||
|
||
// 7. 处理并保存图片
|
||
using (var image = await Image.LoadAsync(file.OpenReadStream()))
|
||
{
|
||
// 调整图片大小(最大200x200)
|
||
/*
|
||
image.Mutate(x => x.Resize(new ResizeOptions
|
||
{
|
||
Size = new Size(200, 200),
|
||
Mode = ResizeMode.Max
|
||
}));
|
||
|
||
*/
|
||
// 强制保存为PNG(高质量)
|
||
await image.SaveAsync(filePath, new PngEncoder
|
||
{
|
||
CompressionLevel = PngCompressionLevel.BestCompression // 最佳压缩
|
||
});
|
||
}
|
||
|
||
// 9. 返回成功响应
|
||
return Ok(new ResponseBase<object>(1000, "LOGO上传成功", null));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "LOGO上传失败");
|
||
throw new BaseException(1004, "LOGO上传失败");
|
||
}
|
||
}
|
||
[HttpPost]
|
||
[Authorize(Roles = "Admin")]
|
||
public async Task<IActionResult> UploadFavicon(IFormFile file)
|
||
{
|
||
try
|
||
{
|
||
// 1. 验证文件
|
||
if (file == null || file.Length == 0)
|
||
{
|
||
throw new BaseException(1001, "缺少文件");
|
||
}
|
||
|
||
// 2. 验证文件大小
|
||
if (file.Length > MaxFileSize)
|
||
{
|
||
throw new BaseException(1001, $"文件大小不能超过{MaxFileSize}");
|
||
}
|
||
|
||
var basePath = _environment.WebRootPath ?? _environment.ContentRootPath;
|
||
// 3. 验证文件类型
|
||
var extension = Path.GetExtension(file.FileName).ToLowerInvariant();
|
||
if (string.IsNullOrEmpty(extension) || extension != ".ico")
|
||
{
|
||
throw new BaseException(1001, "只支持 ICO 格式的图片");
|
||
}
|
||
|
||
|
||
// 3. 保存到网站根目录
|
||
var icoPath = Path.Combine(_environment.WebRootPath, "favicon.ico");
|
||
using (var stream = new FileStream(icoPath, FileMode.Create))
|
||
{
|
||
await file.CopyToAsync(stream);
|
||
}
|
||
|
||
|
||
// 9. 返回成功响应
|
||
return Ok(new ResponseBase<object>(1000, "favicon上传成功", null));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "Favicon上传失败");
|
||
throw new BaseException(1004, "Favicon上传失败");
|
||
}
|
||
}
|
||
[HttpPost]
|
||
[Authorize(Roles = "Admin")]
|
||
public async Task<IActionResult> UploadApi(IFormFile file)
|
||
{
|
||
if (file == null || file.Length == 0)
|
||
throw new BaseException(1001,"请上传文件");
|
||
|
||
// 检查扩展名
|
||
var ext = Path.GetExtension(file.FileName);
|
||
if (ext != ".dll")
|
||
throw new BaseException(1001, "只允许上传DLL");
|
||
|
||
// 插件保存路径
|
||
var saveDir = Path.Combine(_environment.ContentRootPath, "ApiHandler");
|
||
if (!Directory.Exists(saveDir))
|
||
Directory.CreateDirectory(saveDir);
|
||
|
||
var filePath = Path.Combine(saveDir, file.FileName);
|
||
|
||
// 保存文件
|
||
using (var stream = new FileStream(filePath, FileMode.Create))
|
||
{
|
||
await file.CopyToAsync(stream);
|
||
}
|
||
|
||
return Ok(new ResponseBase<object>(1000,"上传成功",null));
|
||
}
|
||
|
||
}
|
||
}
|