using Dpz.Core.MessageQueue.Abstractions;
using Dpz.Core.Public.ViewModel.Messages;

namespace Dpz.Core.Service.RepositoryServiceImpl;

public class BarrageService(
    IRepository<Barrage> repository,
    IMapper mapper,
    IMessagePublisher<AddDanmakuCountMessage> addDanmakuCountPublisher
) : IBarrageService
{
    public async Task<List<VmBarrage>> GetGroupBarragesAsync(string @group)
    {
        var list = await repository
            .SearchFor(x => x.Group == group)
            .OrderByDescending(x => x.SendTime)
            .Take(2000)
            .ToListAsync();
        return mapper.Map<List<VmBarrage>>(list);
    }

    public async Task<int> GetGroupBarrageCountAsync(string groupValue)
    {
        var count = await repository.SearchFor(x => x.Group == groupValue).CountAsync();
        return count;
    }

    public async Task AddBarrageAsync(VmBarrage viewModel)
    {
        var barrage = mapper.Map<Barrage>(viewModel);
        await repository.InsertAsync(barrage);
        // 发布消息到队列,异步更新弹幕计数
        await addDanmakuCountPublisher.PublishAsync(
            new AddDanmakuCountMessage { DanmakuGroup = barrage.Group }
        );
    }

    public async Task<IPagedList<VmBarrage>> GetPageAsync(
        int pageIndex,
        int pageSize,
        string? text = "",
        string? @group = ""
    )
    {
        var predicate = repository.SearchFor(x => true);
        if (!string.IsNullOrEmpty(text))
        {
            predicate = predicate.Where(x => x.Text.Contains(text));
        }

        if (!string.IsNullOrEmpty(group))
        {
            predicate = predicate.Where(x => x.Group == group);
        }
        return await predicate
            .OrderByDescending(x => x.Id)
            .ToPagedListAsync<Barrage, VmBarrage>(pageIndex, pageSize);
    }

    public async Task DeleteAsync(params string[] id)
    {
        await repository.TryDeleteAsync(id);
    }

    public async Task<List<string>> GetGroupsAsync()
    {
        return await repository
            .SearchFor(x => true)
            .GroupBy(x => x.Group)
            .Select(x => x.Key)
            .OrderBy(x => x)
            .ToListAsync();
    }

    public async Task ImportAsync(params VmBarrage[] barrages)
    {
        if (barrages.Any())
        {
            var source = mapper.Map<Barrage[]>(barrages);
            await repository.InsertAsync(source);
        }
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个弹幕服务的实现类,实现了 IBarrageService 接口。让我逐一解释代码的各个部分:

类结构和依赖注入

public class BarrageService(
    IRepository<Barrage> repository,
    IMapper mapper,
    IMessagePublisher<AddDanmakuCountMessage> addDanmakuCountPublisher
) : IBarrageService

使用了 C# 12 的主构造函数语法,注入了三个依赖:

  • IRepository<Barrage>: 弹幕数据仓储,用于数据库操作
  • IMapper: 对象映射器(通常是 AutoMapper),用于实体和视图模型之间的转换
  • IMessagePublisher<AddDanmakuCountMessage>: 消息发布器,用于发布弹幕计数更新消息

主要方法功能

1. 获取群组弹幕列表

public async Task<List<VmBarrage>> GetGroupBarragesAsync(string @group)
  • 根据群组获取最近的 2000 条弹幕
  • 按发送时间倒序排列
  • 将实体转换为视图模型返回

2. 获取群组弹幕数量

public async Task<int> GetGroupBarrageCountAsync(string groupValue)
  • 统计指定群组的弹幕总数

3. 添加弹幕

public async Task AddBarrageAsync(VmBarrage viewModel)
  • 将视图模型转换为实体并保存到数据库
  • 关键特性:异步发布消息到队列,用于更新弹幕计数,实现了解耦和异步处理

4. 分页查询

public async Task<IPagedList<VmBarrage>> GetPageAsync(...)
  • 支持按文本内容和群组进行筛选
  • 返回分页结果
  • 使用了动态查询构建

5. 删除弹幕

public async Task DeleteAsync(params string[] id)
  • 批量删除指定 ID 的弹幕

6. 获取所有群组

public async Task<List<string>> GetGroupsAsync()
  • 获取所有唯一的群组名称,按字母顺序排列

7. 批量导入

public async Task ImportAsync(params VmBarrage[] barrages)
  • 批量导入弹幕数据

设计特点

  1. 异步编程:所有方法都使用 async/await 模式
  2. 消息队列集成:添加弹幕时发布消息,实现异步计数更新
  3. 对象映射:使用 Mapper 进行实体和视图模型的转换
  4. 仓储模式:通过 Repository 抽象数据访问层
  5. 分页支持:提供了分页查询功能
  6. 批量操作:支持批量删除和导入

这是一个典型的领域服务实现,遵循了 DDD(领域驱动设计)和 CQRS 的一些原则,通过消息队列实现了操作的异步化。

评论加载中...