Files
nahodka-back/src/main/java/com/krylov/refound/service/ChatService.java
2026-07-06 00:47:07 +03:00

147 lines
5.0 KiB
Java
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.

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.Map;
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);
messagingTemplate.convertAndSend("/topic/chat/" + chatId, dto);
// Уведомляем получателя об непрочитанных
Long recipientId = chat.getUserOneId().equals(senderId)
? chat.getUserTwoId()
: chat.getUserOneId();
long unreadCount = messageRepository
.countByChatIdAndIsReadFalseAndSenderIdNot(chatId, recipientId);
messagingTemplate.convertAndSend(
"/topic/user/" + recipientId + "/unread",
Map.of("chatId", chatId, "unreadCount", unreadCount)
);
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;
}
public void deleteChat(Long chatId) {
chatRepository.deleteById(chatId);
}
@Transactional
public void markAsRead(Long chatId, Long userId) {
messageRepository.markAsReadByChatIdAndRecipient(chatId, userId);
}
}