added chats with another users

This commit is contained in:
SlimusMinus
2026-06-22 01:08:47 +03:00
parent 194b7efb8a
commit 236d00f2f9
19 changed files with 433 additions and 177 deletions

View File

@@ -0,0 +1,125 @@
package com.krylov.refound.service;
import com.krylov.refound.dto.ChatDto;
import com.krylov.refound.dto.MessageDto;
import com.krylov.refound.entity.Chat;
import com.krylov.refound.entity.Message;
import com.krylov.refound.repository.ChatRepository;
import com.krylov.refound.repository.MessageRepository;
import com.krylov.refound.repository.UserRepository;
import java.util.List;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
public class ChatService {
private final ChatRepository chatRepository;
private final MessageRepository messageRepository;
private final SimpMessagingTemplate messagingTemplate;
private final UserRepository userRepository; // твой существующий репозиторий юзеров
// Создать чат с пользователем (или вернуть существующий)
@Transactional
public ChatDto getOrCreateChat(Long currentUserId, Long otherUserId, Long postId) {
if (currentUserId.equals(otherUserId)) {
throw new IllegalArgumentException("Нельзя создать чат с самим собой");
}
Long u1 = Math.min(currentUserId, otherUserId);
Long u2 = Math.max(currentUserId, otherUserId);
Chat chat = chatRepository.findByUsers(u1, u2)
.orElseGet(() -> {
Chat newChat = new Chat();
newChat.setUserOneId(u1);
newChat.setUserTwoId(u2);
newChat.setPostId(postId);
return chatRepository.save(newChat);
});
return toDto(chat, currentUserId);
}
// Все чаты пользователя
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());
}
// Отправка сообщения (вызывается из 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("Вы не участник этого чата");
}
Message message = new Message();
message.setChatId(chatId);
message.setSenderId(senderId);
message.setContent(content);
message = messageRepository.save(message);
MessageDto dto = toMessageDto(message);
// Отправляем сообщение через WebSocket в топик конкретного чата
messagingTemplate.convertAndSend("/topic/chat/" + chatId, dto);
return dto;
}
private ChatDto toDto(Chat chat, Long currentUserId) {
Long otherUserId = chat.getUserOneId().equals(currentUserId)
? chat.getUserTwoId() : chat.getUserOneId();
ChatDto dto = new ChatDto();
dto.setId(chat.getId());
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());
}
dto.setUnreadCount(
messageRepository.countByChatIdAndIsReadFalseAndSenderIdNot(chat.getId(), currentUserId)
);
return dto;
}
private MessageDto toMessageDto(Message m) {
MessageDto dto = new MessageDto();
dto.setId(m.getId());
dto.setChatId(m.getChatId());
dto.setSenderId(m.getSenderId());
dto.setContent(m.getContent());
dto.setRead(m.isRead());
dto.setCreatedAt(m.getCreatedAt());
return dto;
}
}