网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Security.Cryptography;
using Dpz.Core.EnumLibrary;
using Dpz.Core.Public.ViewModel.V4;
using Dpz.Core.Service.ObjectStorage.Services;
using Dpz.Core.Service.V4.Services;
using Dpz.Core.Web.Models.EventRequest;
using SixLabors.ImageSharp;

namespace Dpz.Core.Web.EventHandlers;

public class PublishPhotoEventHandler(
    IPictureRecordService pictureRecordService,
    IObjectStorageOperation objectStorageService,
    IConfiguration configuration,
    ILogger<PublishPhotoEventHandler> logger
) : IRequestHandler<PublishPhotoRequest, IActionResult>
{
    public async Task<IActionResult> Handle(
        PublishPhotoRequest request,
        CancellationToken cancellationToken
    )
    {
        return string.IsNullOrWhiteSpace(request.Id)
            ? await CreatePhotoRecordAsync(request, cancellationToken)
            : await UpdateInformationAsync(request, cancellationToken);
    }

    private static string? ValidateCreate(PublishPhotoRequest request)
    {
        if (request.Photo is not { Length: > 0 } || !request.Photo.ContentType.Contains("image"))
        {
            return "请选择照片";
        }

        if (request.Tags is not { Count: > 0 })
        {
            return "请选择标签";
        }

        return null;
    }

    private async Task<IActionResult> CreatePhotoRecordAsync(
        PublishPhotoRequest request,
        CancellationToken cancellationToken = default
    )
    {
        var validateMessage = ValidateCreate(request);
        if (!string.IsNullOrWhiteSpace(validateMessage))
        {
            return new JsonResult(new ResultInfo(validateMessage));
        }

        using var memoryStream = new MemoryStream();
        await request.Photo!.CopyToAsync(memoryStream, cancellationToken);
        var bytes = memoryStream.ToArray();

        var path = new List<string> { "images", "album", DateTime.Now.ToString("yyyy-MM") };
        if (
            !string.Equals(
                configuration["AgileConfig:env"],
                "PROD",
                StringComparison.OrdinalIgnoreCase
            )
        )
        {
            path.Insert(0, "test");
        }
        var filename = $"{ObjectId.GenerateNewId()}.{await GetImageFormatAsync(bytes)}";
        var result = await objectStorageService.UploadAsync(
            bytes,
            path,
            filename,
            cancellationToken
        );

        var pictureRecord = new VmPictureRecord
        {
            Creator = request.Creator,
            UploadTime = DateTime.Now,
            Tags = request.Tags,
            Description = request.Description,
            Category = PictureCategory.Album,
            AccessUrl = result.AccessUrl,
            Length = bytes.Length,
            ObjectStorageUploadTime = DateTime.Now,
            Md5 = CalculateMd5(bytes),
            Width = result.Width,
            Height = result.Height,
        };
        var photo = await pictureRecordService.CreateRecordAsync(pictureRecord, cancellationToken);

        return new JsonResult(new ResultInfo(photo));
    }

    private async Task<string?> ValidateUpdateInformationAsync(PublishPhotoRequest request)
    {
        var pictureRecord = await pictureRecordService.GetPictureRecordAsync(request.Id!);
        if (pictureRecord == null)
        {
            return "该照片记录不存在";
        }
        if (pictureRecord.Creator.Id != request.Creator.Id)
        {
            return "没有权限修改该照片信息";
        }
        if (request.Tags is not { Count: > 0 })
        {
            return "请选择标签";
        }

        return null;
    }

    private async Task<IActionResult> UpdateInformationAsync(
        PublishPhotoRequest request,
        CancellationToken cancellationToken = default
    )
    {
        var validateMessage = await ValidateUpdateInformationAsync(request);
        if (!string.IsNullOrWhiteSpace(validateMessage))
        {
            return new JsonResult(new ResultInfo(validateMessage));
        }
        var recordChange = new VmPictureRecordChange
        {
            Category = PictureCategory.Album,
            Description = request.Description,
            Tags = request.Tags,
            Id = request.Id,
        };

        var photo = await pictureRecordService.ChangeInformationAsync(
            recordChange,
            cancellationToken
        );
        return new JsonResult(new ResultInfo(photo));
    }

    private static string CalculateMd5(byte[] bytes)
    {
        var hash = MD5.HashData(bytes);
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
    }

    private async Task<string> GetImageFormatAsync(byte[] bytes)
    {
        try
        {
            using var stream = new MemoryStream(bytes);
            using var image = await Image.LoadAsync(stream);
            return image.Metadata.DecodedImageFormat?.FileExtensions.FirstOrDefault() ?? "jpg";
        }
        catch (Exception e)
        {
            logger.LogError(e, "get image format fail");
            return "jpg";
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

上述代码是一个 ASP.NET Core 的事件处理程序,主要用于处理照片发布请求。它实现了 IRequestHandler<PublishPhotoRequest, IActionResult> 接口,负责处理 PublishPhotoRequest 类型的请求,并返回一个 IActionResult 类型的响应。以下是代码的主要功能和结构的详细解释:

1. 类的构造函数

PublishPhotoEventHandler 类的构造函数接受多个依赖项,包括:

  • IPictureRecordService:用于处理与照片记录相关的服务。
  • IObjectStorageOperation:用于处理对象存储操作的服务。
  • IConfiguration:用于访问应用程序的配置设置。
  • ILogger<PublishPhotoEventHandler>:用于记录日志。

2. 处理请求

Handle 方法是处理请求的主要入口点。它根据请求中是否包含 Id 字段来决定是创建新的照片记录还是更新现有的照片信息:

  • 如果 Id 为空,调用 CreatePhotoRecordAsync 方法创建新的照片记录。
  • 如果 Id 不为空,调用 UpdateInformationAsync 方法更新现有照片的信息。

3. 创建照片记录

CreatePhotoRecordAsync 方法负责创建新的照片记录:

  • 首先调用 ValidateCreate 方法验证请求的有效性,确保上传的照片存在且是有效的图像文件,并且至少选择了一个标签。
  • 如果验证失败,返回一个包含错误信息的 JSON 响应。
  • 将上传的照片复制到内存流中,并获取其字节数组。
  • 根据环境配置生成存储路径和文件名。
  • 调用 objectStorageService.UploadAsync 方法将照片上传到对象存储,并获取上传结果。
  • 创建一个 VmPictureRecord 对象,填充照片的相关信息(如创建者、上传时间、标签、描述等)。
  • 调用 pictureRecordService.CreateRecordAsync 方法将照片记录保存到数据库中,并返回结果。

4. 更新照片信息

UpdateInformationAsync 方法负责更新现有照片的信息:

  • 首先调用 ValidateUpdateInformationAsync 方法验证请求的有效性,确保照片记录存在且请求者有权限修改该记录。
  • 如果验证失败,返回一个包含错误信息的 JSON 响应。
  • 创建一个 VmPictureRecordChange 对象,填充要更新的信息。
  • 调用 pictureRecordService.ChangeInformationAsync 方法更新照片记录,并返回结果。

5. 验证方法

  • ValidateCreate:验证创建请求的有效性,确保照片和标签都已提供。
  • ValidateUpdateInformationAsync:验证更新请求的有效性,确保照片记录存在且请求者有权限进行修改。

6. 辅助方法

  • CalculateMd5:计算给定字节数组的 MD5 哈希值,用于唯一标识照片内容。
  • GetImageFormatAsync:根据字节数组获取图像格式,使用 ImageSharp 库加载图像并返回其文件扩展名。

总结

整体而言,这段代码实现了一个用于处理照片上传和信息更新的事件处理程序,确保请求的有效性,并与对象存储和数据库进行交互,以存储和管理照片记录。

loading