using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.SignalR; using XiangYi.AppApi.Hubs; using XiangYi.Application.DTOs.Requests; using XiangYi.Application.DTOs.Responses; using XiangYi.Application.Interfaces; using XiangYi.Core.Constants; using System.Security.Claims; namespace XiangYi.AppApi.Controllers; /// /// 聊天控制器 /// [ApiController] [Route("api/app/chat")] [Authorize] public class ChatController : ControllerBase { private readonly IChatService _chatService; private readonly IHubContext _hubContext; private readonly ILogger _logger; public ChatController( IChatService chatService, IHubContext hubContext, ILogger logger) { _chatService = chatService; _hubContext = hubContext; _logger = logger; } /// /// 获取会话列表 /// /// 会话列表 [HttpGet("sessions")] public async Task>> GetSessions() { var userId = GetCurrentUserId(); var result = await _chatService.GetSessionsAsync(userId); return ApiResponse>.Success(result); } /// /// 获取消息列表 /// /// 会话ID /// 页码 /// 每页数量 /// 消息列表 [HttpGet("messages")] public async Task>> GetMessages( [FromQuery] long sessionId, [FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 20) { if (sessionId <= 0) { return ApiResponse>.Error(ErrorCodes.InvalidParameter, "会话ID无效"); } var userId = GetCurrentUserId(); // 检查是否有权限访问会话 var canAccess = await _chatService.CanAccessSessionAsync(userId, sessionId); if (!canAccess) { return ApiResponse>.Error(ErrorCodes.Forbidden, "无权访问该会话"); } var request = new GetMessagesRequest { SessionId = sessionId, PageIndex = pageIndex, PageSize = pageSize }; var result = await _chatService.GetMessagesAsync(userId, request); // 标记消息已读 await _chatService.MarkMessagesAsReadAsync(userId, sessionId); return ApiResponse>.Success(result); } /// /// 发送消息 /// /// 发送消息请求 /// 发送结果 [HttpPost("send")] public async Task> SendMessage([FromBody] SendMessageRequest request) { if (request.SessionId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "会话ID无效"); } if (request.ReceiverId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "接收者ID无效"); } var userId = GetCurrentUserId(); // 检查是否有权限访问会话 var canAccess = await _chatService.CanAccessSessionAsync(userId, request.SessionId); if (!canAccess) { return ApiResponse.Error(ErrorCodes.Forbidden, "无权访问该会话"); } var result = await _chatService.SendMessageAsync(userId, request); // 通过 SignalR 推送消息给会话中的所有用户 var messageResponse = new ChatMessageResponse { MessageId = result.MessageId, SessionId = request.SessionId, SenderId = userId, ReceiverId = request.ReceiverId, MessageType = request.MessageType, Content = request.Content, VoiceUrl = request.VoiceUrl, VoiceDuration = request.VoiceDuration, IsRead = false, CreateTime = result.CreateTime, IsSelf = false // 接收者收到时不是自己发的 }; // 推送给会话组(双方都能收到) await _hubContext.SendMessageToSessionAsync(request.SessionId, messageResponse); _logger.LogInformation("消息已通过SignalR推送到会话组: MessageId={MessageId}, SessionId={SessionId}", result.MessageId, request.SessionId); return ApiResponse.Success(result); } /// /// 请求交换微信 /// /// 交换微信请求 /// 交换请求结果 [HttpPost("exchangeWeChat")] public async Task> ExchangeWeChat([FromBody] ExchangeWeChatRequest request) { if (request.SessionId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "会话ID无效"); } if (request.ReceiverId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "接收者ID无效"); } var userId = GetCurrentUserId(); // 检查是否有权限访问会话 var canAccess = await _chatService.CanAccessSessionAsync(userId, request.SessionId); if (!canAccess) { return ApiResponse.Error(ErrorCodes.Forbidden, "无权访问该会话"); } var result = await _chatService.ExchangeWeChatAsync(userId, request); // 通过 SignalR 推送交换请求给会话组 var messageResponse = new ChatMessageResponse { MessageId = result.RequestMessageId, SessionId = request.SessionId, SenderId = userId, ReceiverId = request.ReceiverId, MessageType = 4, // ExchangeWeChatRequest Content = "请求交换微信", IsRead = false, CreateTime = result.CreateTime, IsSelf = false }; await _hubContext.SendMessageToSessionAsync(request.SessionId, messageResponse); _logger.LogInformation("交换微信请求已通过SignalR推送到会话组: MessageId={MessageId}, SessionId={SessionId}", result.RequestMessageId, request.SessionId); return ApiResponse.Success(result); } /// /// 请求交换照片 /// /// 交换照片请求 /// 交换请求结果 [HttpPost("exchangePhoto")] public async Task> ExchangePhoto([FromBody] ExchangePhotoRequest request) { if (request.SessionId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "会话ID无效"); } if (request.ReceiverId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "接收者ID无效"); } var userId = GetCurrentUserId(); // 检查是否有权限访问会话 var canAccess = await _chatService.CanAccessSessionAsync(userId, request.SessionId); if (!canAccess) { return ApiResponse.Error(ErrorCodes.Forbidden, "无权访问该会话"); } var result = await _chatService.ExchangePhotoAsync(userId, request); // 通过 SignalR 推送交换请求给会话组 var messageResponse = new ChatMessageResponse { MessageId = result.RequestMessageId, SessionId = request.SessionId, SenderId = userId, ReceiverId = request.ReceiverId, MessageType = 6, // ExchangePhotoRequest Content = "请求交换照片", IsRead = false, CreateTime = result.CreateTime, IsSelf = false }; await _hubContext.SendMessageToSessionAsync(request.SessionId, messageResponse); _logger.LogInformation("交换照片请求已通过SignalR推送到会话组: MessageId={MessageId}, SessionId={SessionId}", result.RequestMessageId, request.SessionId); return ApiResponse.Success(result); } /// /// 响应交换请求 /// /// 响应请求 /// 响应结果 [HttpPost("respondExchange")] public async Task> RespondExchange([FromBody] RespondExchangeRequest request) { if (request.RequestMessageId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "请求消息ID无效"); } var userId = GetCurrentUserId(); var result = await _chatService.RespondExchangeAsync(userId, request); // 通过 SignalR 推送交换响应结果给会话组(双方都能收到) var resultMessageType = result.RequestMessageType == 4 ? 5 : 7; // 4=ExchangeWeChatRequest->5=Result, 6=ExchangePhotoRequest->7=Result // 构建 ExtraData,确保始终包含 RequestMessageId(即使拒绝时也需要) var extraDataForPush = result.ExchangedData; if (string.IsNullOrEmpty(extraDataForPush)) { // 拒绝时 ExchangedData 为空,需要手动构建包含 RequestMessageId 的数据 extraDataForPush = System.Text.Json.JsonSerializer.Serialize(new { RequestMessageId = result.RequestMessageId, Status = result.IsAgreed ? 1 : 2 }); } var messageResponse = new ChatMessageResponse { MessageId = result.ResultMessageId, SessionId = result.SessionId, SenderId = userId, ReceiverId = result.RequesterId, MessageType = resultMessageType, Content = result.IsAgreed ? "已同意交换" : "已拒绝交换", ExtraData = extraDataForPush, IsRead = false, CreateTime = DateTime.Now, IsSelf = false }; await _hubContext.SendMessageToSessionAsync(result.SessionId, messageResponse); _logger.LogInformation("交换响应已通过SignalR推送到会话组: ResultMessageId={ResultMessageId}, SessionId={SessionId}, IsAgreed={IsAgreed}", result.ResultMessageId, result.SessionId, result.IsAgreed); return ApiResponse.Success(result); } /// /// 获取未读消息数 /// /// 未读消息数 [HttpGet("unreadCount")] public async Task> GetUnreadCount() { var userId = GetCurrentUserId(); var count = await _chatService.GetUnreadCountAsync(userId); return ApiResponse.Success(count); } /// /// 获取或创建会话 /// /// 目标用户ID /// 会话ID [HttpGet("session")] public async Task> GetOrCreateSession([FromQuery] long targetUserId) { if (targetUserId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "目标用户ID无效"); } var userId = GetCurrentUserId(); if (userId == targetUserId) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "不能与自己创建会话"); } var sessionId = await _chatService.GetOrCreateSessionAsync(userId, targetUserId); return ApiResponse.Success(sessionId); } /// /// 删除会话 /// /// 删除会话请求 /// 删除结果 [HttpPost("session/delete")] public async Task DeleteSession([FromBody] DeleteSessionRequest request) { if (request.SessionId <= 0) { return ApiResponse.Error(ErrorCodes.InvalidParameter, "会话ID无效"); } var userId = GetCurrentUserId(); // 检查是否有权限访问会话 var canAccess = await _chatService.CanAccessSessionAsync(userId, request.SessionId); if (!canAccess) { return ApiResponse.Error(ErrorCodes.Forbidden, "无权访问该会话"); } await _chatService.DeleteSessionAsync(userId, request.SessionId); return ApiResponse.Success("删除成功"); } /// /// 获取当前用户ID /// private long GetCurrentUserId() { var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value; return long.TryParse(userIdClaim, out var userId) ? userId : 0; } } /// /// 删除会话请求 /// public class DeleteSessionRequest { /// /// 会话ID /// public long SessionId { get; set; } }