xiangyixiangqin/server/src/XiangYi.Application/Services/ChatService.cs
2026-01-29 20:31:24 +08:00

868 lines
32 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Text.Json;
using Hangfire;
using Microsoft.Extensions.Logging;
using XiangYi.Application.DTOs.Requests;
using XiangYi.Application.DTOs.Responses;
using XiangYi.Application.Interfaces;
using XiangYi.Application.Jobs;
using XiangYi.Core.Constants;
using XiangYi.Core.Entities.Biz;
using XiangYi.Core.Enums;
using XiangYi.Core.Exceptions;
using XiangYi.Core.Interfaces;
namespace XiangYi.Application.Services;
/// <summary>
/// 聊天服务实现
/// </summary>
public class ChatService : IChatService
{
private readonly IRepository<User> _userRepository;
private readonly IRepository<ChatSession> _sessionRepository;
private readonly IRepository<ChatMessage> _messageRepository;
private readonly IRepository<UserProfile> _profileRepository;
private readonly IRepository<UserPhoto> _photoRepository;
private readonly INotificationService _notificationService;
private readonly IBackgroundJobClient _backgroundJobClient;
private readonly ILogger<ChatService> _logger;
public ChatService(
IRepository<User> userRepository,
IRepository<ChatSession> sessionRepository,
IRepository<ChatMessage> messageRepository,
IRepository<UserProfile> profileRepository,
IRepository<UserPhoto> photoRepository,
INotificationService notificationService,
IBackgroundJobClient backgroundJobClient,
ILogger<ChatService> logger)
{
_userRepository = userRepository;
_sessionRepository = sessionRepository;
_messageRepository = messageRepository;
_profileRepository = profileRepository;
_photoRepository = photoRepository;
_notificationService = notificationService;
_backgroundJobClient = backgroundJobClient;
_logger = logger;
}
#region
/// <inheritdoc />
public async Task<SendMessageResponse> SendMessageAsync(long senderId, SendMessageRequest request)
{
// 验证会话存在且用户有权限
var session = await _sessionRepository.GetByIdAsync(request.SessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(senderId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 验证接收者是会话的另一方
var receiverId = GetOtherUserId(senderId, session);
if (receiverId != request.ReceiverId)
{
throw new BusinessException(ErrorCodes.InvalidParameter, "接收者ID不正确");
}
// 验证消息类型
if (request.MessageType < (int)MessageType.Text || request.MessageType > (int)MessageType.Image)
{
throw new BusinessException(ErrorCodes.InvalidMessageType, "无效的消息类型");
}
// 当收到新消息时,自动恢复接收者已删除的会话
var needUpdateSession = false;
if (session.User1Id == receiverId && session.User1Deleted)
{
session.User1Deleted = false;
needUpdateSession = true;
_logger.LogInformation("恢复接收者已删除的会话: SessionId={SessionId}, ReceiverId={ReceiverId}", session.Id, receiverId);
}
else if (session.User2Id == receiverId && session.User2Deleted)
{
session.User2Deleted = false;
needUpdateSession = true;
_logger.LogInformation("恢复接收者已删除的会话: SessionId={SessionId}, ReceiverId={ReceiverId}", session.Id, receiverId);
}
// 检查是否是该会话的首条消息(用于发送首次消息通知)
var isFirstMessage = !await _messageRepository.ExistsAsync(m =>
m.SessionId == request.SessionId &&
m.SenderId == senderId &&
m.Status == (int)MessageStatus.Normal);
// 创建消息
var message = new ChatMessage
{
SessionId = request.SessionId,
SenderId = senderId,
ReceiverId = request.ReceiverId,
MessageType = request.MessageType,
Content = request.Content,
VoiceUrl = request.VoiceUrl,
VoiceDuration = request.VoiceDuration,
Status = (int)MessageStatus.Normal,
IsRead = false,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
var createdMessage = await _messageRepository.AddAsync(message);
// 更新会话最后消息信息和未读数(如果需要恢复会话,也一并更新)
await UpdateSessionLastMessageAsync(session, createdMessage, senderId, needUpdateSession);
_logger.LogInformation("发送消息成功: MessageId={MessageId}, SessionId={SessionId}, SenderId={SenderId}, ReceiverId={ReceiverId}",
createdMessage.Id, request.SessionId, senderId, request.ReceiverId);
// 如果是首次消息,发送通知给接收者(异步,不阻塞主流程)
if (isFirstMessage)
{
_ = Task.Run(async () =>
{
try
{
await _notificationService.SendFirstMessageNotificationAsync(request.ReceiverId, senderId);
}
catch (Exception ex)
{
_logger.LogError(ex, "发送首次消息通知失败: ReceiverId={ReceiverId}, SenderId={SenderId}", request.ReceiverId, senderId);
}
});
}
// 创建5分钟延迟任务检查接收者是否回复
try
{
_backgroundJobClient.Schedule<NotificationJob>(
job => job.SendNoReplyReminderAsync(createdMessage.Id, senderId, request.ReceiverId, request.SessionId),
TimeSpan.FromMinutes(5));
_logger.LogInformation("已创建5分钟未回复提醒任务: MessageId={MessageId}", createdMessage.Id);
}
catch (Exception ex)
{
_logger.LogError(ex, "创建5分钟未回复提醒任务失败: MessageId={MessageId}", createdMessage.Id);
}
return new SendMessageResponse
{
MessageId = createdMessage.Id,
CreateTime = createdMessage.CreateTime
};
}
#endregion
#region
/// <inheritdoc />
public async Task<List<ChatSessionResponse>> GetSessionsAsync(long userId)
{
_logger.LogInformation("获取会话列表: UserId={UserId}", userId);
// 先查询所有相关会话(包括已删除的),用于诊断
var allSessions = await _sessionRepository.GetListAsync(s =>
s.User1Id == userId || s.User2Id == userId);
_logger.LogInformation("用户相关的所有会话(含已删除): Count={Count}, UserId={UserId}", allSessions.Count, userId);
foreach (var s in allSessions)
{
_logger.LogInformation("会话详情: SessionId={SessionId}, User1Id={User1Id}, User2Id={User2Id}, User1Deleted={User1Deleted}, User2Deleted={User2Deleted}, LastMessageTime={LastMessageTime}",
s.Id, s.User1Id, s.User2Id, s.User1Deleted, s.User2Deleted, s.LastMessageTime);
}
// 获取用户参与的所有会话,排除已删除的
var sessions = await _sessionRepository.GetListAsync(s =>
(s.User1Id == userId && !s.User1Deleted) || (s.User2Id == userId && !s.User2Deleted));
_logger.LogInformation("查询到会话数量(排除已删除): Count={Count}, UserId={UserId}", sessions.Count, userId);
// 按最后消息时间排序
sessions = sessions.OrderByDescending(s => s.LastMessageTime ?? s.CreateTime).ToList();
var responses = new List<ChatSessionResponse>();
foreach (var session in sessions)
{
var otherUserId = GetOtherUserId(userId, session);
var otherUser = await _userRepository.GetByIdAsync(otherUserId);
// 获取最后一条消息
ChatMessage? lastMessage = null;
if (session.LastMessageId.HasValue)
{
lastMessage = await _messageRepository.GetByIdAsync(session.LastMessageId.Value);
}
// 获取未读数
var unreadCount = session.User1Id == userId ? session.User1UnreadCount : session.User2UnreadCount;
responses.Add(new ChatSessionResponse
{
SessionId = session.Id,
OtherUserId = otherUserId,
OtherNickname = otherUser?.Nickname,
OtherAvatar = otherUser?.Avatar,
OtherIsRealName = otherUser?.IsRealName ?? false,
LastMessageContent = GetMessageDisplayContent(lastMessage),
LastMessageType = lastMessage?.MessageType,
LastMessageTime = session.LastMessageTime,
UnreadCount = unreadCount
});
}
return responses;
}
/// <inheritdoc />
public async Task<long> GetOrCreateSessionAsync(long userId1, long userId2)
{
// 确保User1Id < User2Id
var (user1Id, user2Id) = userId1 < userId2 ? (userId1, userId2) : (userId2, userId1);
// 查找现有会话
var existingSessions = await _sessionRepository.GetListAsync(s =>
s.User1Id == user1Id && s.User2Id == user2Id);
var existingSession = existingSessions.FirstOrDefault();
if (existingSession != null)
{
// 如果会话存在但被当前用户删除了,恢复它
var needUpdate = false;
if (userId1 == user1Id && existingSession.User1Deleted)
{
existingSession.User1Deleted = false;
needUpdate = true;
}
else if (userId1 == user2Id && existingSession.User2Deleted)
{
existingSession.User2Deleted = false;
needUpdate = true;
}
if (needUpdate)
{
existingSession.UpdateTime = DateTime.Now;
await _sessionRepository.UpdateAsync(existingSession);
_logger.LogInformation("恢复已删除的聊天会话: SessionId={SessionId}, UserId={UserId}",
existingSession.Id, userId1);
}
return existingSession.Id;
}
// 创建新会话
var session = new ChatSession
{
User1Id = user1Id,
User2Id = user2Id,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
var createdSession = await _sessionRepository.AddAsync(session);
_logger.LogInformation("创建聊天会话: User1Id={User1Id}, User2Id={User2Id}, SessionId={SessionId}",
user1Id, user2Id, createdSession.Id);
return createdSession.Id;
}
/// <inheritdoc />
public async Task<bool> CanAccessSessionAsync(long userId, long sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
return false;
}
return IsUserInSession(userId, session);
}
/// <inheritdoc />
public async Task DeleteSessionAsync(long userId, long sessionId)
{
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(userId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 软删除:标记该用户已删除此会话
// 如果是用户1删除设置User1Deleted = true
// 如果是用户2删除设置User2Deleted = true
if (session.User1Id == userId)
{
session.User1Deleted = true;
}
else if (session.User2Id == userId)
{
session.User2Deleted = true;
}
session.UpdateTime = DateTime.Now;
await _sessionRepository.UpdateAsync(session);
_logger.LogInformation("用户删除会话: UserId={UserId}, SessionId={SessionId}", userId, sessionId);
}
#endregion
#region
/// <inheritdoc />
public async Task<PagedResult<ChatMessageResponse>> GetMessagesAsync(long userId, GetMessagesRequest request)
{
// 验证会话存在且用户有权限
var session = await _sessionRepository.GetByIdAsync(request.SessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(userId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 获取消息列表
var (messages, total) = await _messageRepository.GetPagedListAsync(
m => m.SessionId == request.SessionId && m.Status == (int)MessageStatus.Normal,
request.PageIndex,
request.PageSize,
m => m.CreateTime,
isDescending: true);
var responses = messages.Select(m => new ChatMessageResponse
{
MessageId = m.Id,
SessionId = m.SessionId,
SenderId = m.SenderId,
ReceiverId = m.ReceiverId,
MessageType = m.MessageType,
Content = m.Content,
VoiceUrl = m.VoiceUrl,
VoiceDuration = m.VoiceDuration,
ExtraData = m.ExtraData,
IsRead = m.IsRead,
CreateTime = m.CreateTime,
IsSelf = m.SenderId == userId
}).ToList();
return new PagedResult<ChatMessageResponse>
{
Items = responses,
Total = total,
PageIndex = request.PageIndex,
PageSize = request.PageSize
};
}
/// <inheritdoc />
public async Task<int> MarkMessagesAsReadAsync(long userId, long sessionId)
{
// 验证会话存在且用户有权限
var session = await _sessionRepository.GetByIdAsync(sessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(userId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 获取未读消息(接收者是当前用户的消息)
var unreadMessages = await _messageRepository.GetListAsync(m =>
m.SessionId == sessionId &&
m.ReceiverId == userId &&
!m.IsRead &&
m.Status == (int)MessageStatus.Normal);
// 标记消息为已读
foreach (var message in unreadMessages)
{
message.IsRead = true;
message.UpdateTime = DateTime.Now;
await _messageRepository.UpdateAsync(message);
}
// 始终重置会话未读数即使没有未读消息也确保未读数为0
var needUpdateSession = false;
if (session.User1Id == userId && session.User1UnreadCount > 0)
{
session.User1UnreadCount = 0;
needUpdateSession = true;
}
else if (session.User2Id == userId && session.User2UnreadCount > 0)
{
session.User2UnreadCount = 0;
needUpdateSession = true;
}
if (needUpdateSession)
{
session.UpdateTime = DateTime.Now;
await _sessionRepository.UpdateAsync(session);
}
_logger.LogInformation("标记消息已读: SessionId={SessionId}, UserId={UserId}, Count={Count}",
sessionId, userId, unreadMessages.Count);
return unreadMessages.Count;
}
/// <inheritdoc />
public async Task<int> GetUnreadCountAsync(long userId)
{
// 获取用户参与的所有会话
var sessions = await _sessionRepository.GetListAsync(s =>
s.User1Id == userId || s.User2Id == userId);
var totalUnread = 0;
foreach (var session in sessions)
{
totalUnread += session.User1Id == userId ? session.User1UnreadCount : session.User2UnreadCount;
}
return totalUnread;
}
#endregion
#region
/// <inheritdoc />
public async Task<ExchangeRequestResponse> ExchangeWeChatAsync(long senderId, ExchangeWeChatRequest request)
{
// 验证会话存在且用户有权限
var session = await _sessionRepository.GetByIdAsync(request.SessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(senderId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 验证接收者是会话的另一方
var receiverId = GetOtherUserId(senderId, session);
if (receiverId != request.ReceiverId)
{
throw new BusinessException(ErrorCodes.InvalidParameter, "接收者ID不正确");
}
// 创建交换请求消息
var extraData = new ExchangeExtraData
{
Status = 0 // 待响应
};
var message = new ChatMessage
{
SessionId = request.SessionId,
SenderId = senderId,
ReceiverId = request.ReceiverId,
MessageType = (int)MessageType.ExchangeWeChatRequest,
Content = "请求交换微信",
ExtraData = JsonSerializer.Serialize(extraData),
Status = (int)MessageStatus.Normal,
IsRead = false,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
var createdMessage = await _messageRepository.AddAsync(message);
// 更新会话最后消息信息
await UpdateSessionLastMessageAsync(session, createdMessage, senderId);
_logger.LogInformation("发送交换微信请求: MessageId={MessageId}, SessionId={SessionId}, SenderId={SenderId}",
createdMessage.Id, request.SessionId, senderId);
return new ExchangeRequestResponse
{
RequestMessageId = createdMessage.Id,
CreateTime = createdMessage.CreateTime
};
}
/// <inheritdoc />
public async Task<ExchangeRequestResponse> ExchangePhotoAsync(long senderId, ExchangePhotoRequest request)
{
// 验证会话存在且用户有权限
var session = await _sessionRepository.GetByIdAsync(request.SessionId);
if (session == null)
{
throw new BusinessException(ErrorCodes.SessionNotFound, "会话不存在");
}
if (!IsUserInSession(senderId, session))
{
throw new BusinessException(ErrorCodes.SessionAccessDenied, "无权访问该会话");
}
// 验证接收者是会话的另一方
var receiverId = GetOtherUserId(senderId, session);
if (receiverId != request.ReceiverId)
{
throw new BusinessException(ErrorCodes.InvalidParameter, "接收者ID不正确");
}
// 创建交换请求消息
var extraData = new ExchangeExtraData
{
Status = 0 // 待响应
};
var message = new ChatMessage
{
SessionId = request.SessionId,
SenderId = senderId,
ReceiverId = request.ReceiverId,
MessageType = (int)MessageType.ExchangePhotoRequest,
Content = "请求交换照片",
ExtraData = JsonSerializer.Serialize(extraData),
Status = (int)MessageStatus.Normal,
IsRead = false,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
var createdMessage = await _messageRepository.AddAsync(message);
// 更新会话最后消息信息
await UpdateSessionLastMessageAsync(session, createdMessage, senderId);
_logger.LogInformation("发送交换照片请求: MessageId={MessageId}, SessionId={SessionId}, SenderId={SenderId}",
createdMessage.Id, request.SessionId, senderId);
return new ExchangeRequestResponse
{
RequestMessageId = createdMessage.Id,
CreateTime = createdMessage.CreateTime
};
}
/// <inheritdoc />
public async Task<ExchangeRespondResponse> RespondExchangeAsync(long userId, RespondExchangeRequest request)
{
// 获取原始请求消息
var requestMessage = await _messageRepository.GetByIdAsync(request.RequestMessageId);
if (requestMessage == null)
{
throw new BusinessException(ErrorCodes.ExchangeRequestNotFound, "交换请求不存在");
}
// 验证是接收者响应
if (requestMessage.ReceiverId != userId)
{
throw new BusinessException(ErrorCodes.CannotRespondOwnRequest, "只有接收者可以响应交换请求");
}
// 验证消息类型是交换请求
if (requestMessage.MessageType != (int)MessageType.ExchangeWeChatRequest &&
requestMessage.MessageType != (int)MessageType.ExchangePhotoRequest)
{
throw new BusinessException(ErrorCodes.InvalidMessageType, "该消息不是交换请求");
}
// 解析并验证状态
var extraData = string.IsNullOrEmpty(requestMessage.ExtraData)
? new ExchangeExtraData()
: JsonSerializer.Deserialize<ExchangeExtraData>(requestMessage.ExtraData) ?? new ExchangeExtraData();
if (extraData.Status != 0)
{
throw new BusinessException(ErrorCodes.ExchangeAlreadyResponded, "该请求已被响应");
}
// 更新请求消息状态
extraData.Status = request.IsAgreed ? 1 : 2;
// 如果同意,获取双方的数据
string? exchangedData = null;
if (request.IsAgreed)
{
if (requestMessage.MessageType == (int)MessageType.ExchangeWeChatRequest)
{
// 获取双方微信号
var senderProfile = (await _profileRepository.GetListAsync(p => p.UserId == requestMessage.SenderId)).FirstOrDefault();
var receiverProfile = (await _profileRepository.GetListAsync(p => p.UserId == requestMessage.ReceiverId)).FirstOrDefault();
extraData.SenderWeChat = senderProfile?.WeChatNo;
extraData.ReceiverWeChat = receiverProfile?.WeChatNo;
// 包含 RequestMessageId 和 Status 以便前端精确匹配和状态更新
exchangedData = JsonSerializer.Serialize(new
{
RequestMessageId = request.RequestMessageId,
Status = 1, // 已同意
SenderWeChat = extraData.SenderWeChat,
ReceiverWeChat = extraData.ReceiverWeChat
});
}
else
{
// 获取双方照片
var senderPhotos = await _photoRepository.GetListAsync(p => p.UserId == requestMessage.SenderId);
var receiverPhotos = await _photoRepository.GetListAsync(p => p.UserId == requestMessage.ReceiverId);
extraData.SenderPhotos = senderPhotos.OrderBy(p => p.Sort).Select(p => p.PhotoUrl).ToList();
extraData.ReceiverPhotos = receiverPhotos.OrderBy(p => p.Sort).Select(p => p.PhotoUrl).ToList();
// 包含 RequestMessageId 和 Status 以便前端精确匹配和状态更新
exchangedData = JsonSerializer.Serialize(new
{
RequestMessageId = request.RequestMessageId,
Status = 1, // 已同意
SenderPhotos = extraData.SenderPhotos,
ReceiverPhotos = extraData.ReceiverPhotos
});
}
}
// 更新请求消息
requestMessage.ExtraData = JsonSerializer.Serialize(extraData);
requestMessage.UpdateTime = DateTime.Now;
await _messageRepository.UpdateAsync(requestMessage);
// 创建结果消息
var resultMessageType = requestMessage.MessageType == (int)MessageType.ExchangeWeChatRequest
? (int)MessageType.ExchangeWeChatResult
: (int)MessageType.ExchangePhotoResult;
var resultExtraData = new ExchangeExtraData
{
RequestMessageId = request.RequestMessageId,
Status = extraData.Status,
SenderWeChat = extraData.SenderWeChat,
ReceiverWeChat = extraData.ReceiverWeChat,
SenderPhotos = extraData.SenderPhotos,
ReceiverPhotos = extraData.ReceiverPhotos
};
var resultMessage = new ChatMessage
{
SessionId = requestMessage.SessionId,
SenderId = userId,
ReceiverId = requestMessage.SenderId,
MessageType = resultMessageType,
Content = request.IsAgreed ? "已同意交换" : "已拒绝交换",
ExtraData = JsonSerializer.Serialize(resultExtraData),
Status = (int)MessageStatus.Normal,
IsRead = false,
CreateTime = DateTime.Now,
UpdateTime = DateTime.Now
};
var createdResultMessage = await _messageRepository.AddAsync(resultMessage);
// 更新会话最后消息信息
var session = await _sessionRepository.GetByIdAsync(requestMessage.SessionId);
if (session != null)
{
await UpdateSessionLastMessageAsync(session, createdResultMessage, userId);
}
_logger.LogInformation("响应交换请求: RequestMessageId={RequestMessageId}, ResultMessageId={ResultMessageId}, IsAgreed={IsAgreed}",
request.RequestMessageId, createdResultMessage.Id, request.IsAgreed);
return new ExchangeRespondResponse
{
ResultMessageId = createdResultMessage.Id,
IsAgreed = request.IsAgreed,
ExchangedData = exchangedData,
SessionId = requestMessage.SessionId,
RequesterId = requestMessage.SenderId,
RequestMessageType = requestMessage.MessageType,
RequestMessageId = request.RequestMessageId
};
}
#endregion
#region
/// <summary>
/// 检查用户是否在会话中
/// </summary>
private static bool IsUserInSession(long userId, ChatSession session)
{
return session.User1Id == userId || session.User2Id == userId;
}
/// <summary>
/// 获取会话中的另一个用户ID
/// </summary>
private static long GetOtherUserId(long userId, ChatSession session)
{
return session.User1Id == userId ? session.User2Id : session.User1Id;
}
/// <summary>
/// 获取消息显示内容
/// </summary>
private static string? GetMessageDisplayContent(ChatMessage? message)
{
if (message == null) return null;
return message.MessageType switch
{
(int)MessageType.Text => message.Content,
(int)MessageType.Voice => "[语音消息]",
(int)MessageType.Image => "[图片]",
(int)MessageType.ExchangeWeChatRequest => "[请求交换微信]",
(int)MessageType.ExchangeWeChatResult => "[交换微信结果]",
(int)MessageType.ExchangePhotoRequest => "[请求交换照片]",
(int)MessageType.ExchangePhotoResult => "[交换照片结果]",
_ => message.Content
};
}
/// <summary>
/// 更新会话最后消息信息
/// </summary>
/// <param name="session">会话</param>
/// <param name="message">消息</param>
/// <param name="senderId">发送者ID</param>
/// <param name="forceUpdate">是否强制更新(用于恢复已删除会话等场景)</param>
private async Task UpdateSessionLastMessageAsync(ChatSession session, ChatMessage message, long senderId, bool forceUpdate = false)
{
session.LastMessageId = message.Id;
session.LastMessageTime = message.CreateTime;
session.UpdateTime = DateTime.Now;
// 增加接收者的未读数
if (session.User1Id == senderId)
{
session.User2UnreadCount++;
}
else
{
session.User1UnreadCount++;
}
await _sessionRepository.UpdateAsync(session);
}
#endregion
#region
/// <summary>
/// 验证消息是否应该被持久化(静态方法,用于测试)
/// </summary>
/// <param name="messageType">消息类型</param>
/// <param name="content">消息内容</param>
/// <param name="voiceUrl">语音URL</param>
/// <returns>是否应该被持久化</returns>
public static bool ShouldMessageBePersisted(int messageType, string? content, string? voiceUrl)
{
// 文本消息需要有内容
if (messageType == (int)MessageType.Text)
{
return !string.IsNullOrWhiteSpace(content);
}
// 语音消息需要有URL
if (messageType == (int)MessageType.Voice)
{
return !string.IsNullOrWhiteSpace(voiceUrl);
}
// 图片消息需要有内容URL
if (messageType == (int)MessageType.Image)
{
return !string.IsNullOrWhiteSpace(content);
}
return false;
}
/// <summary>
/// 验证消息持久化后可以被查询到(静态方法,用于测试)
/// </summary>
/// <param name="messages">消息列表</param>
/// <param name="messageId">消息ID</param>
/// <returns>消息是否存在于列表中</returns>
public static bool IsMessageInList(List<ChatMessage> messages, long messageId)
{
return messages.Any(m => m.Id == messageId && m.Status == (int)MessageStatus.Normal);
}
/// <summary>
/// 计算交换请求状态流转(静态方法,用于测试)
/// </summary>
/// <param name="currentStatus">当前状态0待响应 1已同意 2已拒绝</param>
/// <param name="isAgreed">是否同意</param>
/// <returns>新状态,如果无法流转返回-1</returns>
public static int CalculateExchangeStatusTransition(int currentStatus, bool isAgreed)
{
// 只有待响应状态可以流转
if (currentStatus != 0)
{
return -1; // 无法流转
}
return isAgreed ? 1 : 2;
}
/// <summary>
/// 验证交换请求状态流转是否有效(静态方法,用于测试)
/// </summary>
/// <param name="fromStatus">原状态</param>
/// <param name="toStatus">目标状态</param>
/// <returns>是否有效</returns>
public static bool IsValidExchangeStatusTransition(int fromStatus, int toStatus)
{
// 只有从待响应(0)可以流转到已同意(1)或已拒绝(2)
if (fromStatus == 0 && (toStatus == 1 || toStatus == 2))
{
return true;
}
return false;
}
/// <summary>
/// 验证交换请求响应后状态是否正确(静态方法,用于测试)
/// </summary>
/// <param name="originalStatus">原始状态</param>
/// <param name="isAgreed">是否同意</param>
/// <param name="newStatus">新状态</param>
/// <returns>状态是否正确</returns>
public static bool IsExchangeResponseStatusCorrect(int originalStatus, bool isAgreed, int newStatus)
{
// 原始状态必须是待响应
if (originalStatus != 0)
{
return false;
}
// 同意应该变成1拒绝应该变成2
var expectedStatus = isAgreed ? 1 : 2;
return newStatus == expectedStatus;
}
#endregion
}