namespace Dpz.Core.Service.RepositoryServiceImpl;

public class ChatRecordService(
    IRepository<ChatRecord> repository,
    IMapper mapper,
    IConfiguration configuration
) : IChatRecordService
{
    public async Task SaveFriendRecordAsync(VmUserInfo sender, string message, VmUserInfo receiver)
    {
        var viewModel = new VmChatRecord
        {
            Type = "friend",
            Message = message,
            Receiver = receiver,
            ReceivGroup = null,
            Sender = sender,
            SendTime = DateTime.Now,
        };
        var entity = mapper.Map<ChatRecord>(viewModel);
        await repository.InsertAsync(entity);
    }

    public async Task SaveGroupRecordAsync(
        VmUserInfo sender,
        string groupId,
        string message,
        string? fontColor
    )
    {
        var viewModel = new VmChatRecord
        {
            Type = "group",
            Message = message,
            FontColor = fontColor,
            Receiver = null,
            Sender = sender,
            ReceivGroup = groupId,
        };
        var entity = mapper.Map<ChatRecord>(viewModel);
        await repository.InsertAsync(entity);
    }

    public async Task SaveRobotRecordAsync(
        VmUserInfo? sender,
        string message,
        string receiveMessage
    )
    {
        var receiver = new VmUserInfo
        {
            Avatar = $"{configuration["CDNBaseAddress"]}/images/ai.jpg",
            Id = "kefu",
            Sign = "星火认知大模型 Spark3.5 Max",
            Name = "星火认知大模型",
            Key = "",
        };
        var send = new VmChatRecord
        {
            Type = "robot",
            Message = message,
            Receiver = receiver,
            Sender = sender,
            ReceivGroup = null,
        };
        var receive = new VmChatRecord
        {
            Type = "robot",
            Message = receiveMessage,
            Receiver = sender,
            Sender = receiver,
            ReceivGroup = null,
        };
        var entity = mapper.Map<ChatRecord>(send);
        await repository.InsertAsync(entity);
        var entity2 = mapper.Map<ChatRecord>(receive);
        await repository.InsertAsync(entity2);
    }

    public async Task<IPagedList<VmChatRecord>> GetFriendRecordAsync(
        string sender,
        string receiver,
        int pageIndex,
        int pageSize
    )
    {
        var source = await repository
            .SearchFor(x =>
                x.Sender != null
                && x.Receiver != null
                && (
                    (x.Sender.Id == sender && x.Receiver.Id == receiver)
                    || (x.Sender.Id == receiver && x.Receiver.Id == sender)
                )
                && x.Type == "friend"
            )
            .OrderByDescending(x => x.SendTime)
            .ToPagedListAsync<ChatRecord, VmChatRecord>(pageIndex, pageSize);
        return source;
    }

    public async Task<IPagedList<VmChatRecord>> GetRobotRecordAsync(
        string sender,
        int pageIndex,
        int pageSize
    )
    {
        var source = await repository
            .SearchFor(x =>
                x.Sender != null
                && x.Receiver != null
                && (
                    (x.Sender.Id == sender && x.Receiver.Id == "kefu")
                    || (x.Sender.Id == "kefu" && x.Receiver.Id == sender)
                )
                && x.Type == "robot"
            )
            .OrderByDescending(x => x.SendTime)
            .ToPagedListAsync<ChatRecord, VmChatRecord>(pageIndex, pageSize);
        return source;
    }

    public async Task<IPagedList<VmChatRecord>> GetGroupRecordAsync(
        string groupId,
        int pageIndex,
        int pageSize
    )
    {
        if (!ObjectId.TryParse(groupId, out var objGroupId))
        {
            return new PagedList<VmChatRecord>(new List<VmChatRecord>(), pageIndex, pageSize);
        }

        var source = await repository
            .SearchFor(x => x.ReceivGroup != null && x.ReceivGroup.Value == objGroupId)
            .OrderByDescending(x => x.SendTime)
            .ToPagedListAsync<ChatRecord, VmChatRecord>(pageIndex, pageSize);
        return source;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这是一个聊天记录服务类的实现,主要负责处理不同类型的聊天记录的保存和查询功能。让我详细解释一下这个代码:

类结构和依赖注入

public class ChatRecordService(
    IRepository<ChatRecord> repository,
    IMapper mapper,
    IConfiguration configuration
) : IChatRecordService

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

  • IRepository<ChatRecord>: 数据访问层,用于操作聊天记录
  • IMapper: 对象映射器(通常是AutoMapper),用于ViewModel和Entity之间的转换
  • IConfiguration: 配置服务,用于获取配置信息

主要功能方法

1. 保存好友聊天记录

public async Task SaveFriendRecordAsync(VmUserInfo sender, string message, VmUserInfo receiver)
  • 创建好友类型的聊天记录
  • 设置发送者、接收者、消息内容和发送时间
  • 通过mapper转换为实体对象并保存到数据库

2. 保存群组聊天记录

public async Task SaveGroupRecordAsync(VmUserInfo sender, string groupId, string message, string? fontColor)
  • 创建群组类型的聊天记录
  • 支持字体颜色设置
  • 接收者为空,但设置了接收群组ID

3. 保存机器人聊天记录

public async Task SaveRobotRecordAsync(VmUserInfo? sender, string message, string receiveMessage)
  • 处理与AI机器人的对话
  • 创建一个固定的机器人用户信息(星火认知大模型)
  • 同时保存用户发送的消息和机器人回复的消息(两条记录)

4. 查询好友聊天记录

public async Task<IPagedList<VmChatRecord>> GetFriendRecordAsync(string sender, string receiver, int pageIndex, int pageSize)
  • 查询两个用户之间的所有聊天记录
  • 使用双向查询条件(A发给B 或 B发给A)
  • 按发送时间降序排列,支持分页

5. 查询机器人聊天记录

public async Task<IPagedList<VmChatRecord>> GetRobotRecordAsync(string sender, int pageIndex, int pageSize)
  • 查询用户与机器人(ID为"kefu")的聊天记录
  • 同样使用双向查询,支持分页

6. 查询群组聊天记录

public async Task<IPagedList<VmChatRecord>> GetGroupRecordAsync(string groupId, int pageIndex, int pageSize)
  • 查询指定群组的聊天记录
  • 包含ObjectId验证,如果群组ID格式不正确则返回空列表
  • 按发送时间降序排列,支持分页

设计特点

  1. 异步操作: 所有方法都是异步的,提高了性能
  2. 分页支持: 查询方法都支持分页,适合处理大量数据
  3. 类型区分: 通过Type字段区分不同类型的聊天(friend、group、robot)
  4. 双向查询: 好友和机器人聊天记录支持双向查询
  5. 错误处理: 在群组记录查询中包含了ObjectId验证
  6. 配置化: 机器人头像地址通过配置文件获取,便于维护

这个服务类很好地封装了聊天记录的业务逻辑,支持多种聊天场景,代码结构清晰,易于维护和扩展。

评论加载中...