using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace UserService.ImageUpload { public class ImageUploadService : IImageUploadService { private readonly ILogger _logger; private static readonly string[] AllowedExtensions = { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp" }; private const long MaxFileSize = 5 * 1024 * 1024; // 5MB private const string UploadFolder = "wwwroot/uploads"; public ImageUploadService(ILogger logger) { _logger = logger; } public bool ValidateImage(IFormFile file, out string errorMessage) { errorMessage = string.Empty; if (file == null || file.Length == 0) { errorMessage = "请选择要上传的文件"; return false; } var ext = Path.GetExtension(file.FileName).ToLowerInvariant(); if (!AllowedExtensions.Contains(ext)) { errorMessage = "只支持上传图片格式:jpg、jpeg、png、gif、bmp、webp"; return false; } if (file.Length > MaxFileSize) { errorMessage = "文件大小不能超过5MB"; return false; } return true; } public async Task<(bool isOk, string path, string fileName, string errorMessage)> UploadImageAsync(IFormFile file) { if (!ValidateImage(file, out var errorMessage)) { return (false, string.Empty, string.Empty, errorMessage); } try { var ext = Path.GetExtension(file.FileName).ToLowerInvariant(); var fileName = Guid.NewGuid().ToString("N") + ext; var uploadPath = Path.Combine(Directory.GetCurrentDirectory(), UploadFolder); if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } var filePath = Path.Combine(uploadPath, fileName); using (var stream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(stream); } var relativePath = $"/uploads/{fileName}"; return (true, relativePath, fileName, string.Empty); } catch (Exception ex) { _logger.LogError(ex, "图片上传失败: {Message}", ex.Message); return (false, string.Empty, string.Empty, $"上传失败:{ex.Message}"); } } } }