Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat:스웨거 문서 수정 #42

Merged
merged 1 commit into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/main/java/com/chat/liveon/auth/entity/Person.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
package com.chat.liveon.auth.entity;

import com.chat.liveon.chat.entity.ChatMessage;
import com.chat.liveon.chat.entity.ChatRoom;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;

@Entity
@Getter
Expand All @@ -24,6 +21,9 @@ public class Person {
private Role role;
private String profilePicture;

@ManyToMany(mappedBy = "participants")
private Set<ChatRoom> chatRooms = new HashSet<>();

public Person(String personId, String personName, String encodedPassword, Role role, String profilePicture) {
this.personId = personId;
this.personName = personName;
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/com/chat/liveon/auth/service/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
import com.chat.liveon.auth.entity.Role;
import com.chat.liveon.auth.exception.AuthenticationFailureException;
import com.chat.liveon.auth.repository.PersonRepository;
import com.chat.liveon.chat.service.ChatRoomService;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -22,10 +22,12 @@
public class AuthService {
private final PasswordEncoder passwordEncoder;
private final PersonRepository personRepository;
private final ChatRoomService chatRoomService;

public AuthService(final PasswordEncoder passwordEncoder, final PersonRepository personRepository) {
public AuthService(final PasswordEncoder passwordEncoder, final PersonRepository personRepository, ChatRoomService chatRoomService) {
this.passwordEncoder = passwordEncoder;
this.personRepository = personRepository;
this.chatRoomService = chatRoomService;
}

@Transactional
Expand All @@ -36,6 +38,7 @@ public void register(RegisterRequest authRequest) {
String encodedPassword = passwordEncoder.encrypt(authRequest.personId(), authRequest.personPassword());
Person person = new Person(authRequest.personId(), authRequest.personName(), encodedPassword, Role.ROLE_USER, authRequest.profilePicture());
personRepository.save(person);
chatRoomService.addUserToAllChatRooms(person);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;
import java.util.Base64;

import static java.util.Objects.hash;

@Component
public class PasswordEncoder {

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/com/chat/liveon/auth/service/PersonService.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
package com.chat.liveon.auth.service;

import com.chat.liveon.auth.entity.Person;
import com.chat.liveon.auth.repository.PersonRepository;
import com.chat.liveon.chat.service.ChatRoomService;
import org.springframework.stereotype.Service;

@Service
public class PersonService {
private final PersonRepository personRepository;

public PersonService(PersonRepository personRepository) {
this.personRepository = personRepository;
}

public Person findByPersonId(Long personId) {
return personRepository.findById(personId).orElseThrow();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,7 @@
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;

import java.util.List;

Expand All @@ -28,13 +25,15 @@ public class ChatMessageController {
@SendTo("/topic/chatroom/{roomId}")
public ChatMessageResponse sendMessage(@DestinationVariable("roomId") String roomId, ChatMessageRequest message) {
Long roomIdLong = Long.parseLong(roomId);

return chatMessageService.sendMessage(roomIdLong, message);
}

@Operation(summary = "이전 채팅 메시지 조회 API")
@GetMapping("/chat-room/{roomId}/messages")
public ResponseEntity<List<ChatMessageResponse>> getChatMessages(@PathVariable("roomId") Long roomId, @RequestParam(name = "page", defaultValue = "0") int page, @RequestParam(name = "size", defaultValue = "20") int size) {
List<ChatMessageResponse> messages = chatMessageService.getMessagesByRoomId(roomId, page, size);

return ResponseEntity.ok(messages);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,33 @@
package com.chat.liveon.chat.controller;

import com.chat.liveon.chat.dto.response.UnreadMessagesResponse;
import com.chat.liveon.chat.service.ChatMessageStatusService;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class ChatMessageStatusController {
private final ChatMessageStatusService chatMessageStatusService;

@PostMapping("/chat-room/{chatRoomId}/read-messages")
public ResponseEntity<Void> markMessagesAsRead(@PathVariable("chatRoomId") Long chatRoomId, HttpSession session) {
String personId = (String) session.getAttribute("personId");
chatMessageStatusService.markMessagesAsRead(chatRoomId, personId);

return ResponseEntity.ok().build();
}

@GetMapping("/chat-room/unread-messages")
public ResponseEntity<List<UnreadMessagesResponse>> getUnreadMessages(HttpSession session) {
String personId = (String) session.getAttribute("personId");
List<UnreadMessagesResponse> response = chatMessageStatusService.getUnreadMessages(personId);

return ResponseEntity.ok(response);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.chat.liveon.chat.dto.request.ChatRoomRequest;
import com.chat.liveon.chat.dto.response.AllChatRoomResponse;
import com.chat.liveon.chat.dto.response.ChatRoomResponse;
import com.chat.liveon.chat.service.ChatMessageStatusService;
import com.chat.liveon.chat.service.ChatRoomService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -20,6 +21,7 @@
public class ChatRoomController {

private final ChatRoomService chatRoomService;
private final ChatMessageStatusService chatMessageStatusService;

@Operation(summary = "채팅방 생성 API")
@PostMapping("/chat-room")
Expand All @@ -32,8 +34,17 @@ public ResponseEntity<ChatRoomResponse> createChatRoom(@RequestBody ChatRoomRequ

@Operation(summary = "채팅방 조회 API")
@GetMapping("/chat-room")
public ResponseEntity<List<AllChatRoomResponse>> getChatRoom() {
List<AllChatRoomResponse> response = chatRoomService.getAllChatRoom();
public ResponseEntity<List<AllChatRoomResponse>> getChatRoom(HttpSession session) {
String personId = (String) session.getAttribute("personId");
List<AllChatRoomResponse> response = chatRoomService.getAllChatRoom(personId);
return ResponseEntity.ok(response);
}

@PostMapping("/chat-room/{chatRoomId}/enter")
public ResponseEntity<Void> enterChatRoom(@PathVariable("chatRoomId") Long chatRoomId, HttpSession session) {
String personId = (String) session.getAttribute("personId");
chatMessageStatusService.markMessagesAsRead(chatRoomId, personId);
chatRoomService.addUserToChatRoom(chatRoomId, personId);
return ResponseEntity.ok().build();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package com.chat.liveon.chat.dto;

public class NotificationMessage {
}
public record NotificationMessage(
Long chatRoomId,
Long unreadCount
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@

public record AllChatRoomResponse(
Long chatRoomId,
String chatRoomName
String chatRoomName,
Long unreadCount
) {}
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package com.chat.liveon.chat.dto.response;

public class UnreadMessagesResponse {
}
public record UnreadMessagesResponse(
Long chatRoomId,
String chatRoomName,
Long unreadCount
) {}
35 changes: 35 additions & 0 deletions src/main/java/com/chat/liveon/chat/entity/ChatMessageStatus.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,39 @@
package com.chat.liveon.chat.entity;

import com.chat.liveon.auth.entity.Person;
import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor
public class ChatMessageStatus {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "chat_message_id")
private ChatMessage chatMessage;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "person_id")
private Person person;

@Column(name = "is_read")
private boolean read;

@Builder
public ChatMessageStatus(ChatMessage chatMessage, Person person) {
this.chatMessage = chatMessage;
this.person = person;
this.read = false;
}

public void read() {
this.read = true;
}
}
16 changes: 15 additions & 1 deletion src/main/java/com/chat/liveon/chat/entity/ChatRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.HashSet;
import java.util.Set;

@Getter
@NoArgsConstructor
@Entity
Expand All @@ -22,9 +25,20 @@ public class ChatRoom {
@JoinColumn(name = "person_id")
private Person person;

@ManyToMany
@JoinTable(name = "chat_room_participants",
joinColumns = @JoinColumn(name = "chat_room_id"),
inverseJoinColumns = @JoinColumn(name = "person_id"))
private Set<Person> participants = new HashSet<>();

@Builder
public ChatRoom(String chatRoomName, Person person) {
this.chatRoomName = chatRoomName;
this.person = person;
}
}

public void addParticipant(Person person) {
participants.add(person);
person.getChatRooms().add(this);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
package com.chat.liveon.chat.repository;

public interface ChatMessageStatusRepository {
import com.chat.liveon.chat.dto.response.UnreadMessagesResponse;
import com.chat.liveon.chat.entity.ChatMessageStatus;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface ChatMessageStatusRepository extends JpaRepository<ChatMessageStatus, Long> {
Long countByChatMessage_ChatRoom_IdAndPerson_PersonIdAndReadFalse(@Param("chatRoomId") Long chatRoomId, @Param("personId") String personId);

@Query("SELECT cms.chatMessage.chatRoom.id, cms.chatMessage.chatRoom.chatRoomName, COUNT(cms) " +
"FROM ChatMessageStatus cms " +
"WHERE cms.person.personId = :personId AND cms.read = false " +
"GROUP BY cms.chatMessage.chatRoom.id, cms.chatMessage.chatRoom.chatRoomName")
List<UnreadMessagesResponse> countUnreadMessagesByChatRoomAndPerson(@Param("personId") String personId);

List<ChatMessageStatus> findByChatMessage_ChatRoom_IdAndPerson_PersonIdAndReadFalse(Long chatRoomId, String personId);

}

Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import com.chat.liveon.chat.entity.ChatRoom;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.lang.NonNull;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;

public interface ChatRoomRepository extends JpaRepository<ChatRoom, Long> {
@NonNull
Optional<ChatRoom> findById(Long roomId);

List<ChatRoom> findByParticipants_PersonId(@Param("personId") String personId);
}
21 changes: 21 additions & 0 deletions src/main/java/com/chat/liveon/chat/service/ChatMessageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@

import com.chat.liveon.auth.entity.Person;
import com.chat.liveon.auth.repository.PersonRepository;
import com.chat.liveon.chat.dto.NotificationMessage;
import com.chat.liveon.chat.dto.request.ChatMessageRequest;
import com.chat.liveon.chat.dto.response.ChatMessageResponse;
import com.chat.liveon.chat.entity.ChatMessage;
import com.chat.liveon.chat.entity.ChatMessageStatus;
import com.chat.liveon.chat.entity.ChatRoom;
import com.chat.liveon.chat.repository.ChatMessageRepository;
import com.chat.liveon.chat.repository.ChatMessageStatusRepository;
import com.chat.liveon.chat.repository.ChatRoomRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Slf4j
Expand All @@ -27,6 +32,8 @@ public class ChatMessageService {
private final ChatMessageRepository chatMessageRepository;
private final ChatRoomRepository chatRoomRepository;
private final PersonRepository personRepository;
private final ChatMessageStatusRepository chatMessageStatusRepository;
private final SimpMessagingTemplate messagingTemplate;

@Transactional
public ChatMessageResponse sendMessage(Long roomId, ChatMessageRequest messageRequest) {
Expand All @@ -44,6 +51,20 @@ public ChatMessageResponse sendMessage(Long roomId, ChatMessageRequest messageRe
chatMessage = chatMessageRepository.save(chatMessage);
log.info("[메시지 전송 성공] 채팅방: {}, 사용자: {}, 메시지: {}", roomId, sender.getPersonName(), messageRequest.message());

Set<Person> participants = chatRoom.getParticipants();
for (Person person : participants) {
if (!person.getPersonId().equals(sender.getPersonId())) {
ChatMessageStatus messageStatus = ChatMessageStatus.builder()
.chatMessage(chatMessage)
.person(person)
.build();
chatMessageStatusRepository.save(messageStatus);
long unreadCount = chatMessageStatusRepository.countByChatMessage_ChatRoom_IdAndPerson_PersonIdAndReadFalse(roomId, person.getPersonId());
NotificationMessage notification = new NotificationMessage(roomId, unreadCount);
messagingTemplate.convertAndSend("/topic/notifications/" + person.getPersonId(), notification);
}
}

return new ChatMessageResponse(
chatMessage.getChatRoom().getId(),
sender.getPersonName(),
Expand Down
Loading