using Dpz.Core.Public.ViewModel.Response;
using Dpz.Core.Service.Mediator.Features.Search;
using Dpz.Core.Service.Mediator.Features.Search.Queries;

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

/// <summary>
/// 处理文章阅读请求,并在提供关键字时补充标题与正文的命中位置。
/// </summary>
public class ArticleReadHandler(
    IRepository<Public.Entity.Article> repository,
    IMediator mediator,
    IMapper mapper
) : IRequestHandler<ArticleReadRequest, ArticleResponse?>
{
    /// <summary>
    /// 执行文章读取与内容匹配。
    /// </summary>
    public async ValueTask<ArticleResponse?> Handle(
        ArticleReadRequest request,
        CancellationToken cancellationToken
    )
    {
        if (!ObjectId.TryParse(request.Id, out var oid))
        {
            return null;
        }

        var articleEntity = await repository.FindAsync(oid, cancellationToken);
        if (articleEntity == null)
        {
            return null;
        }

        var article = mapper.Map<ArticleResponse>(articleEntity);

        var keywordAnalysis = SearchKeywordAnalyzer.Analyze(request.Text);
        var pattern = SearchKeywordAnalyzer.BuildRegexPattern(keywordAnalysis.HighlightTerms);

        if (string.IsNullOrWhiteSpace(pattern))
        {
            return article;
        }

        var response = mapper.Map<Contracts.ArticleResponseSearchResultResponse>(articleEntity);

        var titleSearchRequest = new ContentSearchRequest
        {
            Text = article.Title,
            Pattern = pattern,
        };
        response.TitleSearchResult = await mediator.Send(titleSearchRequest, cancellationToken);

        var contentSearchRequest = new ContentSearchRequest
        {
            Text = article.Markdown,
            Pattern = pattern,
        };
        response.ContentSearchResult = await mediator.Send(contentSearchRequest, cancellationToken);

        return response;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个基于 MediatR 模式的 文章阅读处理器(ArticleReadHandler),它实现了文章读取功能,并在提供关键字时进行内容高亮匹配。

核心功能分析

1. 类结构和依赖注入

public class ArticleReadHandler(
    IRepository<Public.Entity.Article> repository,  // 文章数据仓储
    IMediator mediator,                             // 中介者模式调度器
    IMapper mapper                                  // 对象映射器
) : IRequestHandler<ArticleReadRequest, ArticleResponse?>

使用了 主构造函数语法(C# 12 特性),简洁地注入了三个核心依赖。

2. 主要处理流程

第一步:ID 验证

if (!ObjectId.TryParse(request.Id, out var oid))
{
    return null;
}

验证传入的文章ID是否为有效的 ObjectId 格式(通常用于 MongoDB)。

第二步:文章查询

var articleEntity = await repository.FindAsync(oid, cancellationToken);
if (articleEntity == null)
{
    return null;
}

异步查询数据库中的文章实体,如果不存在则返回 null。

第三步:基础映射

var article = mapper.Map<ArticleResponse>(articleEntity);

将文章实体映射为响应对象。

第四步:关键字分析和搜索增强

var keywordAnalysis = SearchKeywordAnalyzer.Analyze(request.Text);
var pattern = SearchKeywordAnalyzer.BuildRegexPattern(keywordAnalysis.HighlightTerms);
  • 分析用户提供的搜索文本
  • 构建用于高亮显示的正则表达式模式

如果没有有效的搜索模式,直接返回基础文章信息:

if (string.IsNullOrWhiteSpace(pattern))
{
    return article;
}

第五步:搜索结果增强

当存在搜索关键字时,创建增强版本的响应对象:

var response = mapper.Map<Contracts.ArticleResponseSearchResultResponse>(articleEntity);

标题正文内容分别进行搜索匹配:

// 标题搜索
var titleSearchRequest = new ContentSearchRequest
{
    Text = article.Title,
    Pattern = pattern,
};
response.TitleSearchResult = await mediator.Send(titleSearchRequest, cancellationToken);

// 内容搜索
var contentSearchRequest = new ContentSearchRequest
{
    Text = article.Markdown,
    Pattern = pattern,
};
response.ContentSearchResult = await mediator.Send(contentSearchRequest, cancellationToken);

设计特点

  1. 条件增强:根据是否提供搜索关键字,返回不同类型的响应对象
  2. 异步处理:全程使用异步模式,支持高并发
  3. 中介者模式:通过 MediatR 调度搜索功能,实现松耦合
  4. 容错处理:对无效ID和不存在的文章进行了妥善处理
  5. 关注分离:搜索逻辑委托给专门的搜索处理器

这种设计使得文章阅读功能既能满足基本的查看需求,又能在搜索场景下提供增强的内容匹配功能。

评论加载中...