diff --git a/src/main/java/com/umc/networkingService/domain/message/controller/MessageController.java b/src/main/java/com/umc/networkingService/domain/message/controller/MessageController.java new file mode 100644 index 00000000..a8fc0107 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/controller/MessageController.java @@ -0,0 +1,120 @@ +package com.umc.networkingService.domain.message.controller; + + +import com.umc.networkingService.config.security.auth.CurrentMember; +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.request.MessageRequest; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.facade.MessageFacade; +import com.umc.networkingService.global.common.base.BaseResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.UUID; + +@Slf4j +@Tag(name = "채팅 API", description = "채팅 관련 API") +@RestController +@Validated +@RequestMapping("/messages") +@RequiredArgsConstructor +public class MessageController { + + + private final MessageFacade messageFacade; + + @Operation(summary = "쪽지 작성 API",description = "쪽지 작성 API") + @PostMapping("/{messageRoomId}") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE002", description = "존재하지 않는 쪽지방"), + }) + public BaseResponse + postMessage( + @CurrentMember Member member, + @PathVariable UUID messageRoomId, + @RequestBody MessageRequest.Message message + ){ + return BaseResponse.onSuccess(messageFacade.postMessage(member, messageRoomId, message)); + } + + @Operation(summary = "쪽지 수정 API",description = "쪽지 수정 API") + @PatchMapping("/{messageId}") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE001", description = "존재하지 않는 쪽지") + }) + public BaseResponse + patchMessage( + @CurrentMember Member member, + @PathVariable UUID messageId, + @RequestBody MessageRequest.Message message + ){ + return BaseResponse.onSuccess(messageFacade.patchMessage(member, messageId, message)); + } + + @Operation(summary = "쪽지 삭제 API",description = "쪽지 삭제 API") + @DeleteMapping("/{messageId}") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE001", description = "존재하지 않는 쪽지") + }) + public BaseResponse + deleteMessage( + @CurrentMember Member member, + @PathVariable UUID messageId + ){ + return BaseResponse.onSuccess(messageFacade.deleteMessage(member, messageId)); + } + + @Operation(summary = "쪽지 상세 조회 API",description = "쪽지 상세 조회 API (페이지 0부터 시작) (isAnonymous가 true일 경우 익명인 메시지))") + @GetMapping("/{messageRoomId}") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE002", description = "존재하지 않는 쪽지방"), + @ApiResponse(responseCode = "COMMON500", description = "페이지 에러, 0<=page를 입력해주세요") + }) + public BaseResponse + joinMessages( + @CurrentMember Member member, + @PathVariable UUID messageRoomId, + @RequestParam(name= "page") int page //페이징 처리 + ){ + return BaseResponse.onSuccess(messageFacade.joinMessages(member, messageRoomId, page)); + } + + @Operation(summary = "쪽지함 조회 API",description = "쪽지함 조회 API (isAnonymous가 true일 경우 상대가 익명인 메시지)") + @GetMapping("") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE005", description = "최신 쪽지를 찾을 수 없습니다."), + }) + public BaseResponse + joinMessageRooms( + @CurrentMember Member member + ){ + return BaseResponse.onSuccess(messageFacade.joinMessageRooms(member)); + } + + @Operation(summary = "쪽지 시작하기 API",description = "쪽지 시작하기 API") + @PostMapping("") + @ApiResponses( value = { + @ApiResponse(responseCode = "COMMON200", description = "성공"), + @ApiResponse(responseCode = "MESSAGE003", description = "이미 존재하는 쪽지방"), + @ApiResponse(responseCode = "MESSAGE004", description = "보내는 메시지가 없음") + }) + public BaseResponse + startMessage( + @CurrentMember Member member, + @RequestBody MessageRequest.StartMessageRoom messageRoom + ){ + return BaseResponse.onSuccess(messageFacade.createMessageRoom(member, messageRoom.getMessageRoomUserId(), messageRoom.getIsAnonymous(), messageRoom.getMessageContent())); + } + +} diff --git a/src/main/java/com/umc/networkingService/domain/message/dto/request/MessageRequest.java b/src/main/java/com/umc/networkingService/domain/message/dto/request/MessageRequest.java new file mode 100644 index 00000000..85f67b82 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/dto/request/MessageRequest.java @@ -0,0 +1,31 @@ +package com.umc.networkingService.domain.message.dto.request; + +import com.umc.networkingService.global.common.enums.Semester; +import lombok.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.UUID; + +public class MessageRequest { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor // 쪽지 생성, 수정 + public static class Message { + //todo: 글자수 제한 + String message; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor // 쪽지방 생성 + public static class StartMessageRoom{ + @NonNull + UUID messageRoomUserId; + Boolean isAnonymous; //기본적으로 실명 + @NonNull + String messageContent; + } +} diff --git a/src/main/java/com/umc/networkingService/domain/message/dto/response/MessageResponse.java b/src/main/java/com/umc/networkingService/domain/message/dto/response/MessageResponse.java new file mode 100644 index 00000000..cbe56396 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/dto/response/MessageResponse.java @@ -0,0 +1,74 @@ +package com.umc.networkingService.domain.message.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.UUID; + +public class MessageResponse { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinMessageRooms { //쪽지함 조회 + List messageRooms; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinMessageRoom{ + UUID messageRoomId; + UUID messageRoomUserId; + String messageRoomUserName; + String recentMessage; + String recentMessageTime; + Boolean isAnonymous; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinMessages { //쪽지 조회 + List JoinMessage; + UUID messageRoomId; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class JoinMessage + { + UUID messageId; + String message; + String messageTime; + String messageMemberName; + UUID messageMemberId; + Boolean isAnonymous; //해당 메시지의 주인이 익명인지 + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MessageRoomId + { + UUID messageRoomId; + } + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class MessageId + { + UUID messageId; + } +} diff --git a/src/main/java/com/umc/networkingService/domain/message/entity/Message.java b/src/main/java/com/umc/networkingService/domain/message/entity/Message.java index c3e57424..0f410c7c 100644 --- a/src/main/java/com/umc/networkingService/domain/message/entity/Message.java +++ b/src/main/java/com/umc/networkingService/domain/message/entity/Message.java @@ -2,9 +2,7 @@ import com.umc.networkingService.global.common.base.BaseEntity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; @@ -12,6 +10,8 @@ @Getter @Entity +@Builder +@AllArgsConstructor @NoArgsConstructor(access= AccessLevel.PROTECTED) @SQLRestriction("deleted_at is null") public class Message extends BaseEntity { @@ -30,4 +30,8 @@ public class Message extends BaseEntity { @Column(nullable = false) private Boolean isSender; + public void updateContent(String content) { + this.content = content; + } + } diff --git a/src/main/java/com/umc/networkingService/domain/message/entity/MessageRoom.java b/src/main/java/com/umc/networkingService/domain/message/entity/MessageRoom.java index 7a16e150..f79d9c7d 100644 --- a/src/main/java/com/umc/networkingService/domain/message/entity/MessageRoom.java +++ b/src/main/java/com/umc/networkingService/domain/message/entity/MessageRoom.java @@ -1,10 +1,9 @@ package com.umc.networkingService.domain.message.entity; +import com.umc.networkingService.domain.member.entity.Member; import com.umc.networkingService.global.common.base.BaseEntity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.hibernate.annotations.SQLRestriction; import org.hibernate.annotations.UuidGenerator; @@ -12,6 +11,8 @@ @Getter @Entity +@Builder +@AllArgsConstructor @NoArgsConstructor(access= AccessLevel.PROTECTED) @SQLRestriction("deleted_at is null") public class MessageRoom extends BaseEntity { @@ -22,13 +23,24 @@ public class MessageRoom extends BaseEntity { private UUID id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn - private Message sender; + @JoinColumn(name = "sender_id") + private Member sender; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn - private Message receiver; + @JoinColumn(name = "receiver_id") + private Member receiver; @Column(nullable = false) private Boolean isAnonymous; } + +/* +1. 쪽지를 보내기 시작할 떄, 처음 보낸 사람이 익명이라면, 받는 사람에게는 보낸 사람이 익명으로 뜸 +2. 익명으로 보낸 사람 입장에서는 받는 사람이 실명으로 뜸 +3. 그럼,A 입장에서는 A가 B에게 익명으로 쪽지를 보낸 채팅방, A와 B가 실명으로 쪽지를 주고받는 채팅방이 따로 생길 수도 있음 +4. A가 B에게 익명인 채팅방은 하나만 생성됨 (A가 sender 일떄, isAnonymous = true) isAnonymous = true -> receiver 입장에서 sender가 익명 +5. A가 B에게 실명인 채팅방은 하나만 생성됨 (A가 sender 일떄, isAnonymous = false) +6. A가 receiver 일떄, isAnonymous = false인 채팅방이 2개가 생김 +-> 필드 바꿔야함 +(그럼 A가 ) +*/ \ No newline at end of file diff --git a/src/main/java/com/umc/networkingService/domain/message/facade/MessageFacade.java b/src/main/java/com/umc/networkingService/domain/message/facade/MessageFacade.java new file mode 100644 index 00000000..68335fe4 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/facade/MessageFacade.java @@ -0,0 +1,45 @@ +package com.umc.networkingService.domain.message.facade; + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.request.MessageRequest; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.service.MessageRoomService; +import com.umc.networkingService.domain.message.service.MessageService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class MessageFacade { + + private final MessageService messageService; + private final MessageRoomService messageRoomService; + + public MessageResponse.MessageId postMessage(Member sender, UUID messageRoomId, MessageRequest.Message message) { + return messageService.postMessage(sender, messageRoomId, message, messageRoomService); + } + + public MessageResponse.MessageId patchMessage(Member member, UUID messageId, MessageRequest.Message message) { + return messageService.patchMessage(member, messageId, message); + } + + public MessageResponse.MessageId deleteMessage(Member member, UUID messageId) { + return messageService.deleteMessage(member, messageId); + } + + public MessageResponse.JoinMessages joinMessages(Member member, UUID messageRoomId, int page) { + return messageService.joinMessages(member, messageRoomId, page, messageRoomService); + } + + public MessageResponse.MessageRoomId createMessageRoom(Member member, UUID receiverId, boolean isAnonymous, String content){ + MessageResponse.MessageRoomId resposnse = messageRoomService.createMessageRoom(member, receiverId, isAnonymous, content); + messageService.postMessage(member, resposnse.getMessageRoomId(), MessageRequest.Message.builder().message(content).build(), messageRoomService); + return resposnse; + } + + public MessageResponse.JoinMessageRooms joinMessageRooms(Member member) { + return messageRoomService.joinMessageRooms(member, messageService); + } +} diff --git a/src/main/java/com/umc/networkingService/domain/message/mapper/MessageMapper.java b/src/main/java/com/umc/networkingService/domain/message/mapper/MessageMapper.java new file mode 100644 index 00000000..2b3d6798 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/mapper/MessageMapper.java @@ -0,0 +1,27 @@ +package com.umc.networkingService.domain.message.mapper; + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.entity.Message; +import com.umc.networkingService.domain.message.entity.MessageRoom; + +import java.time.format.DateTimeFormatter; + + +public class MessageMapper { + + //쪽지방 리스트 조회ㅓ + public static MessageResponse.JoinMessageRoom toJoinMessageRoom(MessageRoom messageRoom, Message recentMessage, Member messageRoomUser){ + return MessageResponse.JoinMessageRoom.builder() + .messageRoomId(messageRoom.getId()) + .messageRoomUserId(messageRoomUser.getId()) + .messageRoomUserName(messageRoomUser.getNickname()+"/"+messageRoomUser.getName()) + .recentMessage(recentMessage.getContent()) + .recentMessageTime( + recentMessage.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss")) + ) + .isAnonymous(messageRoom.getIsAnonymous()&&messageRoom.getSender().getId().equals(messageRoomUser.getId())) + .build(); + + } +} diff --git a/src/main/java/com/umc/networkingService/domain/message/repository/MessageRepository.java b/src/main/java/com/umc/networkingService/domain/message/repository/MessageRepository.java new file mode 100644 index 00000000..0dc229c1 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/repository/MessageRepository.java @@ -0,0 +1,19 @@ +package com.umc.networkingService.domain.message.repository; + +import com.umc.networkingService.domain.message.entity.Message; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.Optional; +import java.util.UUID; + +public interface MessageRepository extends JpaRepository { + Optional findTopByMessageRoomOrderByCreatedAtDesc(MessageRoom messageRoom); + + //메시지룸 아이디로 메시지 리스트 최신순 조회, 페이징 20개씩 + Page findAllByMessageRoomIdOrderByCreatedAtDesc(UUID messageRoomId, PageRequest pageRequest); + +} diff --git a/src/main/java/com/umc/networkingService/domain/message/repository/MessageRoomRepository.java b/src/main/java/com/umc/networkingService/domain/message/repository/MessageRoomRepository.java new file mode 100644 index 00000000..474fb9ba --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/repository/MessageRoomRepository.java @@ -0,0 +1,13 @@ +package com.umc.networkingService.domain.message.repository; + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; +import java.util.UUID; + +public interface MessageRoomRepository extends JpaRepository { + boolean existsByReceiverAndSenderAndIsAnonymous(Member receiver, Member sender, boolean isAnonymous); + List findAllByReceiverOrSender(Member receiver, Member sender); +} diff --git a/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomService.java b/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomService.java new file mode 100644 index 00000000..76cd03e2 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomService.java @@ -0,0 +1,21 @@ +package com.umc.networkingService.domain.message.service; + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +public interface MessageRoomService { + //채팅방 생성 + @Transactional + MessageResponse.MessageRoomId createMessageRoom(Member member, UUID receiverId, boolean isAnonymous, String content); + + @Transactional(readOnly = true) + MessageResponse.JoinMessageRooms joinMessageRooms(Member member, MessageService messageService); + + //아이디로 채팅방 찾기 + @Transactional(readOnly = true) + MessageRoom findByMessageRoomId(UUID messageRoomId); +} diff --git a/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomServiceImpl.java b/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomServiceImpl.java new file mode 100644 index 00000000..dd82a6e1 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/service/MessageRoomServiceImpl.java @@ -0,0 +1,87 @@ +package com.umc.networkingService.domain.message.service; + + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.member.service.MemberService; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.entity.Message; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import com.umc.networkingService.domain.message.mapper.MessageMapper; +import com.umc.networkingService.domain.message.repository.MessageRoomRepository; +import com.umc.networkingService.global.common.exception.RestApiException; +import com.umc.networkingService.global.common.exception.code.MessageErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Comparator; +import java.util.List; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class MessageRoomServiceImpl implements MessageRoomService{ + + private final MessageRoomRepository messageRoomRepository; + + private final MemberService memberService; + + //채팅방 생성 + @Override + public MessageResponse.MessageRoomId createMessageRoom(Member member, UUID receiverId, boolean isAnonymous, String content){ + Member receiver = memberService.findByMemberId(receiverId); + + //메시지룸 이미 있는지 확인 + if(messageRoomRepository.existsByReceiverAndSenderAndIsAnonymous(receiver, member, isAnonymous)){ + throw new RestApiException(MessageErrorCode.ALREADY_EXIST_MESSAGE_ROOM); + } + + //메시지룸 생성은 메시지를 보내야지 생성 + if(content.isEmpty()){ + throw new RestApiException(MessageErrorCode.EMPTY_MESSAGE); + } + + return MessageResponse.MessageRoomId.builder() + .messageRoomId(messageRoomRepository.save( + MessageRoom.builder() + .sender(member) + .receiver(receiver) + .isAnonymous(isAnonymous) //true면 sender가 익명 + .build() + ).getId()) + .build(); + } + + @Override + public MessageResponse.JoinMessageRooms joinMessageRooms(Member member, MessageService messageService){ //메시지룸 리스트 조회 + List messageRooms = messageRoomRepository.findAllByReceiverOrSender(member, member); + + return MessageResponse.JoinMessageRooms.builder() //메시지룸 리스트 + .messageRooms( + messageRooms.stream() + .map(messageRoom -> { + //유저가 receiver인데 isAnonymous가 true면 JoinMessageRoom의 isAnonymous는 true + + Member messageRoomUser = (messageRoom.getSender().getId().equals(member.getId())) //request를 보낸 유저가 sender면 receiver, receiver면 sender 반환 + ? messageRoom.getReceiver() + : messageRoom.getSender(); + + Message recentMessage = messageService.findRecentMessageByMessageRoom(messageRoom); //가장 최신의 메시지 찾기 + + return MessageMapper.toJoinMessageRoom(messageRoom, recentMessage, messageRoomUser); //메시지룸 리스트 조회 + + }) + .sorted(Comparator.comparing(MessageResponse.JoinMessageRoom::getRecentMessageTime).reversed()) //최신순으로 정렬 + .toList() + ) + .build(); + + } + + //아이디로 채팅방 찾기 + @Override + public MessageRoom findByMessageRoomId(UUID messageRoomId){ + return messageRoomRepository.findById(messageRoomId) + .orElseThrow(() -> new RestApiException(MessageErrorCode.NOT_FOUND_MESSAGE_ROOM)); + } + +} diff --git a/src/main/java/com/umc/networkingService/domain/message/service/MessageService.java b/src/main/java/com/umc/networkingService/domain/message/service/MessageService.java new file mode 100644 index 00000000..c7e3441a --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/service/MessageService.java @@ -0,0 +1,32 @@ +package com.umc.networkingService.domain.message.service; + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.request.MessageRequest; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.entity.Message; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import org.springframework.transaction.annotation.Transactional; + +import java.util.UUID; + +public interface MessageService { + @Transactional + MessageResponse.MessageId postMessage(Member sender, UUID messageRoomId, MessageRequest.Message message, MessageRoomService messageRoomService); + + //쪽지 수정 + @Transactional + MessageResponse.MessageId patchMessage(Member member, UUID messageId, MessageRequest.Message message); + + //쪽지 삭제 + @Transactional + MessageResponse.MessageId deleteMessage(Member member, UUID messageId); + + //쪽지방의 메시지 리스트 조회 + @Transactional(readOnly = true) + MessageResponse.JoinMessages joinMessages(Member member ,UUID messageRoomId, int page, MessageRoomService messageRoomService); + + + //가장 최신의 메시지 찾기 + @Transactional(readOnly = true) + Message findRecentMessageByMessageRoom(MessageRoom messageRoom); +} diff --git a/src/main/java/com/umc/networkingService/domain/message/service/MessageServiceImpl.java b/src/main/java/com/umc/networkingService/domain/message/service/MessageServiceImpl.java new file mode 100644 index 00000000..1b94e298 --- /dev/null +++ b/src/main/java/com/umc/networkingService/domain/message/service/MessageServiceImpl.java @@ -0,0 +1,108 @@ +package com.umc.networkingService.domain.message.service; + + +import com.umc.networkingService.domain.member.entity.Member; +import com.umc.networkingService.domain.message.dto.request.MessageRequest; +import com.umc.networkingService.domain.message.dto.response.MessageResponse; +import com.umc.networkingService.domain.message.entity.Message; +import com.umc.networkingService.domain.message.entity.MessageRoom; +import com.umc.networkingService.domain.message.repository.MessageRepository; +import com.umc.networkingService.global.common.exception.RestApiException; +import com.umc.networkingService.global.common.exception.code.GlobalErrorCode; +import com.umc.networkingService.global.common.exception.code.MessageErrorCode; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; + +import java.time.format.DateTimeFormatter; +import java.util.UUID; + +@Service +@RequiredArgsConstructor +public class MessageServiceImpl implements MessageService{ + + private final MessageRepository messageRepository; + + + //쪽지 보내기 + @Override + public MessageResponse.MessageId postMessage(Member sender, UUID messageRoomId, MessageRequest.Message message, MessageRoomService messageRoomService){ + if(message.getMessage().isEmpty()) + throw new RestApiException(MessageErrorCode.EMPTY_MESSAGE); + + return MessageResponse.MessageId.builder() + .messageId( + messageRepository.save( + Message.builder() + .messageRoom(messageRoomService.findByMessageRoomId(messageRoomId)) + .content(message.getMessage()) + .isSender(sender.getId().equals(messageRoomService.findByMessageRoomId(messageRoomId).getSender().getId())) + .build()).getId() + ).build(); + } + + //쪽지 수정 + @Override + public MessageResponse.MessageId patchMessage(Member member, UUID messageId, MessageRequest.Message message){ + messageRepository.findById(messageId) + .orElseThrow(() -> new RestApiException(MessageErrorCode.NOT_FOUND_MESSAGE)) + .updateContent(message.getMessage()); + return MessageResponse.MessageId.builder().messageId(messageId).build(); + } + + //쪽지 삭제 + @Override + public MessageResponse.MessageId deleteMessage(Member member, UUID messageId){ + messageRepository.findById(messageId) + .orElseThrow(() -> new RestApiException(MessageErrorCode.NOT_FOUND_MESSAGE)) + .delete(); + return MessageResponse.MessageId.builder().messageId(messageId).build(); + } + + //쪽지방의 메시지 리스트 조회 + @Override + public MessageResponse.JoinMessages joinMessages(Member member ,UUID messageRoomId, int page, MessageRoomService messageRoomService){ + + if(page < 0) + throw new RestApiException(GlobalErrorCode._INTERNAL_PAGE_ERROR); + + MessageRoom messageRoom = messageRoomService.findByMessageRoomId(messageRoomId); + + Page messages = messageRepository.findAllByMessageRoomIdOrderByCreatedAtDesc( + messageRoomId, PageRequest.of(page, 20)); //20개씩 페이징 + + return MessageResponse.JoinMessages.builder() + .messageRoomId(messageRoomId) + .JoinMessage( + messages.getContent().stream() + .map(message -> MessageResponse.JoinMessage.builder() + .messageId(message.getId()) + .message(message.getContent()) + .messageTime(message.getCreatedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"))) + .messageMemberName( //해당 메시지를 보낸 사람 이름 + Boolean.TRUE.equals(message.getIsSender()) + ? messageRoom.getSender().getNickname()+"/"+messageRoom.getSender().getName() + : messageRoom.getReceiver().getNickname()+"/"+messageRoom.getReceiver().getName() + ) + .messageMemberId( //해당 메시지를 보낸 사람 아이디 + Boolean.TRUE.equals(message.getIsSender()) + ? messageRoom.getSender().getId() + : messageRoom.getReceiver().getId() + ) //해당 메시지를 보낸 사람이 익명인지 여부 + .isAnonymous(message.getIsSender()&&messageRoom.getIsAnonymous()) + .build() + ).toList() + ) + .build(); + + } + + + //가장 최신의 메시지 찾기 + @Override + public Message findRecentMessageByMessageRoom(MessageRoom messageRoom){ + return messageRepository.findTopByMessageRoomOrderByCreatedAtDesc(messageRoom) + .orElseThrow(() -> new RestApiException(MessageErrorCode.NOT_FOUND_RECENT_MESSAGE)); + } +} diff --git a/src/main/java/com/umc/networkingService/domain/university/dto/request/UniversityRequest.java b/src/main/java/com/umc/networkingService/domain/university/dto/request/UniversityRequest.java index f8968d92..89fc39ba 100644 --- a/src/main/java/com/umc/networkingService/domain/university/dto/request/UniversityRequest.java +++ b/src/main/java/com/umc/networkingService/domain/university/dto/request/UniversityRequest.java @@ -14,7 +14,7 @@ public class UniversityRequest { @NoArgsConstructor @AllArgsConstructor // 대학교 생성, 수정 public static class universityInfo { - //todo:마스코트 처리 + //todo: 마스코트 처리 String universityName; MultipartFile universityLogo; MultipartFile semesterLogo; diff --git a/src/main/java/com/umc/networkingService/global/common/exception/code/GlobalErrorCode.java b/src/main/java/com/umc/networkingService/global/common/exception/code/GlobalErrorCode.java index 0d2ef54b..7bb22e58 100644 --- a/src/main/java/com/umc/networkingService/global/common/exception/code/GlobalErrorCode.java +++ b/src/main/java/com/umc/networkingService/global/common/exception/code/GlobalErrorCode.java @@ -18,6 +18,7 @@ public enum GlobalErrorCode implements ErrorCodeInterface { _FORBIDDEN(HttpStatus.FORBIDDEN, "COMMON403", "금지된 요청입니다."), _NOT_FOUND(HttpStatus.NOT_FOUND, "COMMON404", "요청한 정보를 찾을 수 없습니다."), _METHOD_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, "COMMON405", "Argument Type이 올바르지 않습니다."), + _INTERNAL_PAGE_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, "COMMON500", "페이지 에러, 0 이상의 페이지를 입력해주세요"), // For test TEMP_EXCEPTION(HttpStatus.BAD_REQUEST, "TEMP4001", "예외처리 테스트입니다."), diff --git a/src/main/java/com/umc/networkingService/global/common/exception/code/MessageErrorCode.java b/src/main/java/com/umc/networkingService/global/common/exception/code/MessageErrorCode.java new file mode 100644 index 00000000..7b80b62f --- /dev/null +++ b/src/main/java/com/umc/networkingService/global/common/exception/code/MessageErrorCode.java @@ -0,0 +1,32 @@ +package com.umc.networkingService.global.common.exception.code; + +import com.umc.networkingService.global.common.exception.ErrorCode; +import com.umc.networkingService.global.common.exception.ErrorCodeInterface; +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +@AllArgsConstructor +public enum MessageErrorCode implements ErrorCodeInterface { + + NOT_FOUND_MESSAGE(HttpStatus.BAD_REQUEST, "MESSAGE001", "존재하지 않는 쪽지입니다."), + NOT_FOUND_MESSAGE_ROOM(HttpStatus.BAD_REQUEST, "MESSAGE002", "존재하지 않는 쪽지방입니다."), + ALREADY_EXIST_MESSAGE_ROOM(HttpStatus.BAD_REQUEST, "MESSAGE003", "이미 존재하는 쪽지방입니다."), + EMPTY_MESSAGE(HttpStatus.BAD_REQUEST, "MESSAGE004", "메시지가 비었습니다."), + NOT_FOUND_RECENT_MESSAGE(HttpStatus.BAD_REQUEST, "MESSAGE005", "최신 메시지를 찾을 수 없습니다."), + ; + + private final HttpStatus httpStatus; + private final String code; + private final String message; + + @Override + public ErrorCode getErrorCode() { + return ErrorCode.builder() + .httpStatus(httpStatus) + .code(code) + .message(message) + .build(); + } +} diff --git a/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java b/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java index 4d21e45e..6f78ceba 100644 --- a/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java +++ b/src/test/java/com/umc/networkingService/support/ServiceIntegrationTestConfig.java @@ -109,7 +109,6 @@ protected void setToken(UUID memberId) { protected Mascot createMascot() { return mascotRepository.save( Mascot.builder() - .dialogue("테스트") .startLevel(1) .endLevel(10) .build()