using Dpz.Core.Service.Mediator.Features.Media.Contracts;
using Dpz.Core.Service.Mediator.Features.Media.Events;

namespace Dpz.Core.Service.Mediator.Features.Article.Events;

/// <summary>
/// 尝试为文章补充图片元信息。
/// </summary>
public class ArticleImageMetadataCollectedHandler(
    IRepository<global::Dpz.Core.Public.Entity.Article> repository,
    ILogger<ArticleImageMetadataCollectedHandler> logger
) : INotificationHandler<ImageMetadataCollectedNotification>
{
    /// <summary>
    /// 根据通知中的数据 ID 尝试更新文章集合。
    /// </summary>
    public async ValueTask Handle(
        ImageMetadataCollectedNotification notification,
        CancellationToken cancellationToken
    )
    {
        var article = await repository.TryGetAsync(notification.Id, cancellationToken);
        if (article == null)
        {
            return;
        }

        var images = ImageMetadataBackfillHelper.MergeByUrl(
            article.ImagesAddress,
            article.Images,
            notification.Images
        );
        var update = Builders<global::Dpz.Core.Public.Entity.Article>
            .Update.Set(x => x.MainImageMetadata, images.Count > 0 ? images[0] : null)
            .Set(x => x.Images, images);

        var result = await repository.UpdateAsync(
            x => x.Id == article.Id,
            update,
            cancellationToken
        );
        if (result.ModifiedCount > 0)
        {
            logger.LogInformation(
                "文章图片元信息已回填: Id={Id}, Count={Count},Title={Title}",
                notification.Id,
                images.Count,
                article.Title
            );
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

代码解释

这是一个基于 Mediator 模式的事件处理器类,用于处理图片元数据收集完成后的文章信息更新。

核心功能

当系统收集到图片的元数据信息时,该处理器会尝试将这些元数据回填到相关的文章实体中。

类结构分析

类定义

public class ArticleImageMetadataCollectedHandler : 
    INotificationHandler<ImageMetadataCollectedNotification>
  • 实现接口: INotificationHandler<T> - 标准的 Mediator 通知处理器接口
  • 处理的通知: ImageMetadataCollectedNotification - 图片元数据收集完成的通知

依赖注入

通过主构造函数注入两个依赖:

  • IRepository<Article>: 文章数据仓储,用于数据库操作
  • ILogger: 日志记录器

处理流程

1. 获取文章实体

var article = await repository.TryGetAsync(notification.Id, cancellationToken);

根据通知中的 ID 尝试获取对应的文章,如果不存在则直接返回。

2. 合并图片元数据

var images = ImageMetadataBackfillHelper.MergeByUrl(
    article.ImagesAddress,
    article.Images,
    notification.Images
);

使用辅助方法合并:

  • 文章原有的图片地址列表
  • 文章现有的图片元数据
  • 通知中新收集的图片元数据

3. 构建更新操作

var update = Builders<Article>
    .Update.Set(x => x.MainImageMetadata, images.Count > 0 ? images[0] : null)
    .Set(x => x.Images, images);

使用 MongoDB 的 Update Builder 构建更新操作:

  • MainImageMetadata: 设置主图片元数据(取第一张图片,如果有的话)
  • Images: 更新完整的图片元数据列表

4. 执行更新并记录日志

var result = await repository.UpdateAsync(
    x => x.Id == article.Id,
    update,
    cancellationToken
);

执行数据库更新操作,并在成功时记录日志信息。

设计亮点

  1. 异步处理: 使用 ValueTask 提高性能
  2. 取消支持: 完整的 CancellationToken 支持
  3. 防御性编程: 检查文章是否存在
  4. 可观测性: 详细的日志记录,包含文章 ID、图片数量和标题
  5. MongoDB 优化: 使用 Builders 模式构建高效的更新操作

应用场景

这个处理器通常用于以下场景:

  • 异步图片处理完成后的元数据回填
  • 图片尺寸、格式等信息的补充
  • 主图自动设置
  • 文章图片集合的维护
评论加载中...