using FreeSql; using LiveForum.Code.Base; using LiveForum.IService.Messages; using LiveForum.IService.Others; using LiveForum.IService.Users; using LiveForum.Model; using LiveForum.Model.Dto.Users; using LiveForum.Model.Events; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text.Json; using System.Threading.Tasks; namespace LiveForum.Service.Messages { /// /// 消息事件处理器实现 /// 将事件转换为数据库消息记录(重量级,包含用户信息查询和快照构造) /// public class MessageEventHandler : IMessageEventHandler { private readonly IBaseRepository _messagesRepository; private readonly IBaseRepository _usersRepository; private readonly IBaseRepository _postsRepository; private readonly IBaseRepository _commentsRepository; private readonly IUserInfoService _userInfoService; private readonly ILogger _logger; public MessageEventHandler( IBaseRepository messagesRepository, IBaseRepository usersRepository, IBaseRepository postsRepository, IBaseRepository commentsRepository, IUserInfoService userInfoService, ILogger logger) { _messagesRepository = messagesRepository; _usersRepository = usersRepository; _postsRepository = postsRepository; _commentsRepository = commentsRepository; _userInfoService = userInfoService; _logger = logger; } /// /// 处理点赞事件 /// public async Task HandleLikeEventAsync(LikeEvent evt) { try { // 幂等性检查 if (await IsEventProcessedAsync(evt.EventId)) { _logger.LogWarning("[EventHandler] 事件已处理过,跳过: {EventId}", evt.EventId); return; } // 查询触发者用户信息 var sender = await _usersRepository.Select .Where(x => x.Id == evt.TriggerId) .FirstAsync(); if (sender == null) { _logger.LogWarning("[EventHandler] 用户不存在,跳过点赞消息创建: TriggerId={TriggerId}", evt.TriggerId); return; } // 使用服务转换为 UserInfoDto(自动获取认证类型数据) var senderInfo = await _userInfoService.ToUserInfoDtoAsync(sender); // 组装消息标题和内容 string messageTitle; string messageContent; if (evt.ContentType == 1) { messageTitle = $"点赞了我的帖子"; messageContent = $"帖子标题:{evt.Content?.PostTitle ?? ""}"; } else if (evt.ContentType == 2) { messageTitle = $"点赞了我的评论"; messageContent = $"评论内容:{TruncateText(evt.Content?.CommentContent, 50)}"; } else if (evt.ContentType == 3) // 送花 { messageTitle = $"给我送花"; messageContent = evt.Content?.PostTitle ?? ""; // "送了 X 朵花" } else { messageTitle = $"点赞了我"; messageContent = ""; } // 序列化用户信息 var senderInfoJson = JsonSerializer.Serialize(senderInfo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); var contentSnapshotJson = JsonSerializer.Serialize(evt.Content, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); // 创建消息记录 var message = new T_Messages { ReceiverId = evt.ReceiverId, SenderId = evt.TriggerId, MessageType = 2, // 点赞消息 MessageTitle = messageTitle, MessageContent = messageContent, ContentType = evt.ContentType, ContentId = evt.ContentId, IsRead = false, SenderInfo = senderInfoJson, EventId = evt.EventId, ContentSnapshot = contentSnapshotJson, CreatedAt = evt.OccurredAt }; await _messagesRepository.InsertAsync(message); _logger.LogInformation( "[EventHandler] 点赞消息已创建: EventId={EventId}, ContentType={ContentType}, ContentId={ContentId}", evt.EventId, evt.ContentType, evt.ContentId); } catch (Exception ex) { _logger.LogError(ex, "[EventHandler] 处理点赞事件失败: EventId={EventId}", evt.EventId); throw; } } /// /// 处理评论回复事件 /// public async Task HandleCommentReplyEventAsync(CommentReplyEvent evt) { try { // 幂等性检查 if (await IsEventProcessedAsync(evt.EventId)) { _logger.LogWarning("[EventHandler] 事件已处理过,跳过: {EventId}", evt.EventId); return; } // 查询触发者用户信息 var sender = await _usersRepository.Select .Where(x => x.Id == evt.TriggerId) .FirstAsync(); if (sender == null) { _logger.LogWarning("[EventHandler] 用户不存在,跳过回复消息创建: TriggerId={TriggerId}", evt.TriggerId); return; } // 使用服务转换为 UserInfoDto(自动获取认证类型数据) var senderInfo = await _userInfoService.ToUserInfoDtoAsync(sender); // 组装消息标题 string messageTitle; if (evt.IsDirectComment) { messageTitle = $"评论了你的帖子"; } else { messageTitle = $"回复了我的评论"; } string messageContent = $"回复内容:{TruncateText(evt.CommentContent, 50)}"; // 序列化用户信息 var senderInfoJson = JsonSerializer.Serialize(senderInfo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); // 组装内容快照 var contentSnapshot = new ContentSnapshot { PostId = evt.PostId, PostTitle = evt.PostTitle, CommentId = evt.CommentId, CommentContent = evt.CommentContent }; var contentSnapshotJson = JsonSerializer.Serialize(contentSnapshot, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); // 创建消息记录 var message = new T_Messages { ReceiverId = evt.ReceiverId, SenderId = evt.TriggerId, MessageType = 1, // 回复消息 MessageTitle = messageTitle, MessageContent = messageContent, MyCommentContent = evt.MyCommentContent, // 保存我的评论内容 ContentType = 2, // 评论类型 ContentId = evt.CommentId, IsRead = false, SenderInfo = senderInfoJson, EventId = evt.EventId, ContentSnapshot = contentSnapshotJson, CreatedAt = evt.OccurredAt }; await _messagesRepository.InsertAsync(message); _logger.LogInformation( "[EventHandler] 评论回复消息已创建: EventId={EventId}, CommentId={CommentId}, IsDirectComment={IsDirectComment}", evt.EventId, evt.CommentId, evt.IsDirectComment); } catch (Exception ex) { _logger.LogError(ex, "[EventHandler] 处理评论回复事件失败: EventId={EventId}", evt.EventId); throw; } } /// /// 处理自定义消息事件 /// public async Task HandleCustomMessageEventAsync(CustomMessageEvent evt) { try { // 幂等性检查 if (await IsEventProcessedAsync(evt.EventId)) { _logger.LogWarning("[EventHandler] 事件已处理过,跳过: {EventId}", evt.EventId); return; } // 查询触发者用户信息 var sender = await _usersRepository.Select .Where(x => x.Id == evt.TriggerId) .FirstAsync(); if (sender == null) { _logger.LogWarning("[EventHandler] 用户不存在,跳过自定义消息创建: TriggerId={TriggerId}", evt.TriggerId); return; } // 使用服务转换为 UserInfoDto(自动获取认证类型数据) var senderInfo = await _userInfoService.ToUserInfoDtoAsync(sender); // 序列化用户信息 var senderInfoJson = JsonSerializer.Serialize(senderInfo, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }); // 创建消息记录 var message = new T_Messages { ReceiverId = evt.ReceiverId, SenderId = evt.TriggerId, MessageType = evt.MessageType, // 1-回复,2-点赞 MessageTitle = evt.Title, MessageContent = evt.Content, MyCommentContent = evt.MyCommentContent, ContentType = 0, // 自定义消息没有具体内容类型 ContentId = null, IsRead = false, SenderInfo = senderInfoJson, EventId = evt.EventId, ContentSnapshot = null, CreatedAt = evt.OccurredAt }; await _messagesRepository.InsertAsync(message); _logger.LogInformation( "[EventHandler] 自定义消息已创建: EventId={EventId}, MessageType={MessageType}", evt.EventId, evt.MessageType); } catch (Exception ex) { _logger.LogError(ex, "[EventHandler] 处理自定义消息事件失败: EventId={EventId}", evt.EventId); throw; } } /// /// 检查事件是否已经处理过(幂等性检查) /// private async Task IsEventProcessedAsync(string eventId) { if (string.IsNullOrEmpty(eventId)) { return false; } var exists = await _messagesRepository.Select .Where(x => x.EventId == eventId) .AnyAsync(); return exists; } /// /// 截断文本 /// private string TruncateText(string text, int maxLength) { if (string.IsNullOrEmpty(text) || text.Length <= maxLength) { return text ?? ""; } return text.Substring(0, maxLength) + "..."; } } }