feat: 修复用户头像上传功能,支持Base64图片上传到腾讯云COS
- 修复 updateUserInfo 接口路由(update_userinfo -> updateUserInfo) - IUploadService 添加 UploadBase64ImageAsync 方法 - UploadService 实现 Base64 图片解析和 COS 上传 - UserController 注入 IUploadService 替代本地保存逻辑 - HoneyBox.Api 添加对 HoneyBox.Admin.Business 的项目引用
This commit is contained in:
parent
72145441ee
commit
a95a2852d4
|
|
@ -22,6 +22,14 @@ public interface IUploadService
|
|||
/// <returns>上传响应列表</returns>
|
||||
Task<List<UploadResponse>> UploadImagesAsync(List<IFormFile> files);
|
||||
|
||||
/// <summary>
|
||||
/// 上传Base64编码的图片
|
||||
/// </summary>
|
||||
/// <param name="base64Image">Base64编码的图片数据(可包含data:image/xxx;base64,前缀)</param>
|
||||
/// <param name="fileNamePrefix">文件名前缀,如 "avatar"</param>
|
||||
/// <returns>上传后的图片URL,失败返回null</returns>
|
||||
Task<string?> UploadBase64ImageAsync(string base64Image, string fileNamePrefix = "image");
|
||||
|
||||
/// <summary>
|
||||
/// 获取预签名上传URL(客户端直传)
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -101,6 +101,95 @@ public class UploadService : IUploadService
|
|||
return results;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<string?> UploadBase64ImageAsync(string base64Image, string fileNamePrefix = "image")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(base64Image))
|
||||
{
|
||||
_logger.LogWarning("Base64图片数据为空");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 解析Base64数据和MIME类型
|
||||
string base64Data;
|
||||
string contentType = "image/png";
|
||||
string extension = ".png";
|
||||
|
||||
if (base64Image.Contains(','))
|
||||
{
|
||||
// 格式: data:image/png;base64,xxxxx
|
||||
var parts = base64Image.Split(',');
|
||||
base64Data = parts[1];
|
||||
|
||||
// 解析MIME类型
|
||||
var header = parts[0]; // data:image/png;base64
|
||||
if (header.Contains(':') && header.Contains(';'))
|
||||
{
|
||||
var mimeType = header.Split(':')[1].Split(';')[0];
|
||||
contentType = mimeType;
|
||||
extension = mimeType switch
|
||||
{
|
||||
"image/jpeg" => ".jpg",
|
||||
"image/jpg" => ".jpg",
|
||||
"image/png" => ".png",
|
||||
"image/gif" => ".gif",
|
||||
"image/webp" => ".webp",
|
||||
_ => ".png"
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
base64Data = base64Image;
|
||||
}
|
||||
|
||||
// 解码Base64数据
|
||||
byte[] imageBytes;
|
||||
try
|
||||
{
|
||||
imageBytes = Convert.FromBase64String(base64Data);
|
||||
}
|
||||
catch (FormatException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Base64解码失败");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 验证文件大小 (10MB)
|
||||
if (imageBytes.Length > 10 * 1024 * 1024)
|
||||
{
|
||||
_logger.LogWarning("Base64图片大小超过限制: {Size} bytes", imageBytes.Length);
|
||||
return null;
|
||||
}
|
||||
|
||||
// 生成文件名
|
||||
var fileName = $"{fileNamePrefix}_{DateTime.UtcNow:yyyyMMddHHmmss}{extension}";
|
||||
|
||||
// 获取存储提供者并上传
|
||||
var provider = await GetStorageProviderAsync();
|
||||
using var stream = new MemoryStream(imageBytes);
|
||||
var result = await provider.UploadAsync(stream, fileName, contentType);
|
||||
|
||||
if (result.Success)
|
||||
{
|
||||
_logger.LogInformation("Base64图片上传成功: {Url}", result.Url);
|
||||
return result.Url;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("Base64图片上传失败: {Error}", result.ErrorMessage);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Base64图片上传异常");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证文件
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System.Security.Claims;
|
||||
using HoneyBox.Admin.Business.Services.Interfaces;
|
||||
using HoneyBox.Core.Interfaces;
|
||||
using HoneyBox.Model.Base;
|
||||
using HoneyBox.Model.Models.Asset;
|
||||
|
|
@ -24,6 +25,7 @@ public class UserController : ControllerBase
|
|||
private readonly IAssetService _assetService;
|
||||
private readonly IVipService _vipService;
|
||||
private readonly IQuanYiService _quanYiService;
|
||||
private readonly IUploadService _uploadService;
|
||||
private readonly ILogger<UserController> _logger;
|
||||
|
||||
public UserController(
|
||||
|
|
@ -32,6 +34,7 @@ public class UserController : ControllerBase
|
|||
IAssetService assetService,
|
||||
IVipService vipService,
|
||||
IQuanYiService quanYiService,
|
||||
IUploadService uploadService,
|
||||
ILogger<UserController> logger)
|
||||
{
|
||||
_userService = userService;
|
||||
|
|
@ -39,6 +42,7 @@ public class UserController : ControllerBase
|
|||
_assetService = assetService;
|
||||
_vipService = vipService;
|
||||
_quanYiService = quanYiService;
|
||||
_uploadService = uploadService;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
|
|
@ -166,12 +170,17 @@ public class UserController : ControllerBase
|
|||
if (!string.IsNullOrWhiteSpace(request.Imagebase))
|
||||
{
|
||||
// Base64图片上传到腾讯云COS
|
||||
var headimgUrl = await UploadBase64ImageAsync(request.Imagebase, userId.Value);
|
||||
var headimgUrl = await _uploadService.UploadBase64ImageAsync(request.Imagebase, $"avatar_{userId}");
|
||||
if (!string.IsNullOrWhiteSpace(headimgUrl))
|
||||
{
|
||||
updateDto.Headimg = headimgUrl;
|
||||
hasUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogWarning("头像上传失败: UserId={UserId}", userId);
|
||||
return ApiResponse.Fail("头像上传失败,请重试");
|
||||
}
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(request.Headimg))
|
||||
{
|
||||
|
|
@ -524,51 +533,5 @@ public class UserController : ControllerBase
|
|||
return userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传Base64图片到腾讯云COS
|
||||
/// </summary>
|
||||
/// <param name="base64Image">Base64编码的图片数据</param>
|
||||
/// <param name="userId">用户ID</param>
|
||||
/// <returns>上传后的图片URL</returns>
|
||||
private async Task<string?> UploadBase64ImageAsync(string base64Image, int userId)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 移除Base64前缀(如果有)
|
||||
var base64Data = base64Image;
|
||||
if (base64Image.Contains(","))
|
||||
{
|
||||
base64Data = base64Image.Split(',')[1];
|
||||
}
|
||||
|
||||
// 解码Base64数据
|
||||
var imageBytes = Convert.FromBase64String(base64Data);
|
||||
|
||||
// TODO: 实现腾讯云COS上传
|
||||
// 目前返回一个占位URL,实际应该上传到COS并返回真实URL
|
||||
// 可以在后续添加ICosUploadService接口和实现
|
||||
|
||||
// 临时方案:将图片保存到本地并返回相对路径
|
||||
var fileName = $"avatar_{userId}_{DateTime.UtcNow:yyyyMMddHHmmss}.png";
|
||||
var uploadPath = Path.Combine("wwwroot", "uploads", "avatars");
|
||||
|
||||
if (!Directory.Exists(uploadPath))
|
||||
{
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
}
|
||||
|
||||
var filePath = Path.Combine(uploadPath, fileName);
|
||||
await System.IO.File.WriteAllBytesAsync(filePath, imageBytes);
|
||||
|
||||
// 返回相对URL
|
||||
return $"/uploads/avatars/{fileName}";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to upload base64 image for user: {UserId}", userId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
<ProjectReference Include="..\HoneyBox.Model\HoneyBox.Model.csproj" />
|
||||
<ProjectReference Include="..\HoneyBox.Core\HoneyBox.Core.csproj" />
|
||||
<ProjectReference Include="..\HoneyBox.Infrastructure\HoneyBox.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\HoneyBox.Admin.Business\HoneyBox.Admin.Business.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user