fixed controllers
This commit is contained in:
@@ -11,17 +11,22 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.messaging.simp.SimpMessagingTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ChatService {
|
||||
|
||||
private final ChatRepository chatRepository;
|
||||
private final MessageRepository messageRepository;
|
||||
private final SimpMessagingTemplate messagingTemplate;
|
||||
private final UserRepository userRepository; // твой существующий репозиторий юзеров
|
||||
private final UserRepository userRepository;
|
||||
|
||||
// Создать чат с пользователем (или вернуть существующий)
|
||||
@Transactional
|
||||
@@ -46,28 +51,28 @@ public class ChatService {
|
||||
}
|
||||
|
||||
// Все чаты пользователя
|
||||
@Transactional(readOnly = true)
|
||||
public List<ChatDto> getUserChats(Long userId) {
|
||||
return chatRepository.findAllByUserId(userId).stream()
|
||||
.map(c -> toDto(c, userId))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
// История сообщений в чате
|
||||
public List<MessageDto> getMessages(Long chatId) {
|
||||
return messageRepository.findByChatIdOrderByCreatedAtAsc(chatId).stream()
|
||||
.map(this::toMessageDto)
|
||||
.collect(Collectors.toList());
|
||||
// История сообщений в чате, с пагинацией и проверкой доступа
|
||||
@Transactional(readOnly = true)
|
||||
public Page<MessageDto> getMessages(Long chatId, Long userId, Pageable pageable) {
|
||||
Chat chat = getChatOrThrow(chatId);
|
||||
checkParticipant(chat, userId);
|
||||
|
||||
return messageRepository.findByChatIdOrderByCreatedAtDesc(chatId, pageable)
|
||||
.map(this::toMessageDto);
|
||||
}
|
||||
|
||||
// Отправка сообщения (вызывается из WebSocket контроллера)
|
||||
@Transactional
|
||||
public MessageDto sendMessage(Long senderId, Long chatId, String content) {
|
||||
Chat chat = chatRepository.findById(chatId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Чат не найден"));
|
||||
|
||||
if (!chat.getUserOneId().equals(senderId) && !chat.getUserTwoId().equals(senderId)) {
|
||||
throw new SecurityException("Вы не участник этого чата");
|
||||
}
|
||||
Chat chat = getChatOrThrow(chatId);
|
||||
checkParticipant(chat, senderId);
|
||||
|
||||
Message message = new Message();
|
||||
message.setChatId(chatId);
|
||||
@@ -95,6 +100,33 @@ public class ChatService {
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteChat(Long chatId, Long userId) {
|
||||
Chat chat = getChatOrThrow(chatId);
|
||||
checkParticipant(chat, userId);
|
||||
chatRepository.deleteById(chatId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void markAsRead(Long chatId, Long userId) {
|
||||
Chat chat = getChatOrThrow(chatId);
|
||||
checkParticipant(chat, userId);
|
||||
messageRepository.markAsReadByChatIdAndRecipient(chatId, userId);
|
||||
}
|
||||
|
||||
// ---------- вспомогательные методы ----------
|
||||
|
||||
private Chat getChatOrThrow(Long chatId) {
|
||||
return chatRepository.findById(chatId)
|
||||
.orElseThrow(() -> new IllegalArgumentException("Чат не найден"));
|
||||
}
|
||||
|
||||
private void checkParticipant(Chat chat, Long userId) {
|
||||
if (!chat.getUserOneId().equals(userId) && !chat.getUserTwoId().equals(userId)) {
|
||||
throw new SecurityException("Вы не участник этого чата");
|
||||
}
|
||||
}
|
||||
|
||||
private ChatDto toDto(Chat chat, Long currentUserId) {
|
||||
Long otherUserId = chat.getUserOneId().equals(currentUserId)
|
||||
? chat.getUserTwoId() : chat.getUserOneId();
|
||||
@@ -104,18 +136,17 @@ public class ChatService {
|
||||
dto.setOtherUserId(otherUserId);
|
||||
dto.setPostId(chat.getPostId());
|
||||
|
||||
// Подтягиваем имя/аватар собеседника из твоего UserRepository
|
||||
userRepository.findById(otherUserId).ifPresent(user -> {
|
||||
dto.setOtherUserName(user.getName() + " " + user.getLastName());
|
||||
dto.setOtherUserAvatar(user.getAvatarUrl());
|
||||
});
|
||||
|
||||
List<Message> messages = messageRepository.findByChatIdOrderByCreatedAtAsc(chat.getId());
|
||||
if (!messages.isEmpty()) {
|
||||
Message last = messages.getLast();
|
||||
dto.setLastMessage(last.getContent());
|
||||
dto.setLastMessageAt(last.getCreatedAt());
|
||||
}
|
||||
// без N+1: берём только последнее сообщение, а не всю историю
|
||||
messageRepository.findFirstByChatIdOrderByCreatedAtDesc(chat.getId())
|
||||
.ifPresent(last -> {
|
||||
dto.setLastMessage(last.getContent());
|
||||
dto.setLastMessageAt(last.getCreatedAt());
|
||||
});
|
||||
|
||||
dto.setUnreadCount(
|
||||
messageRepository.countByChatIdAndIsReadFalseAndSenderIdNot(chat.getId(), currentUserId)
|
||||
@@ -134,13 +165,4 @@ public class ChatService {
|
||||
dto.setCreatedAt(m.getCreatedAt());
|
||||
return dto;
|
||||
}
|
||||
|
||||
public void deleteChat(Long chatId) {
|
||||
chatRepository.deleteById(chatId);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void markAsRead(Long chatId, Long userId) {
|
||||
messageRepository.markAsReadByChatIdAndRecipient(chatId, userId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user