diff --git a/src/main/java/com/salemale/domain/chat/controller/ChatController.java b/src/main/java/com/salemale/domain/chat/controller/ChatController.java index 6529e7b..e77f512 100644 --- a/src/main/java/com/salemale/domain/chat/controller/ChatController.java +++ b/src/main/java/com/salemale/domain/chat/controller/ChatController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.*; // REST API용 어노테이션 (@GetMapping 등) import java.util.List; // 리스트 응답용 import java.net.URI; //응답 헤더 생성 +import com.salemale.domain.chat.dto.BlockStatusResponse; //차단 여부 import com.salemale.domain.chat.dto.ChatDtos.ChatIdUnread; /** @@ -109,7 +110,7 @@ public ResponseEntity> readAllInChat( -채팅방에서 대화 상대 차단 */ @Operation(summary = "대화 상대 차단", description = "상대방을 차단하고 상대방이 경매 등록한 물품이 보이지 않게 됨.") - @PostMapping("/{chatId}/block") + @PostMapping("/chats/{chatId}/block") public ResponseEntity> blockPartner( @RequestHeader("user-id") Long me, @PathVariable Long chatId @@ -123,7 +124,7 @@ public ResponseEntity> blockPartner( -채팅방에서 대화 상대 차단 해제 */ @Operation(summary = "대화 상대 차단 해제", description = "상대방을 차단 해제.") - @PostMapping("/{chatId}/unblock") + @PostMapping("/chats/{chatId}/unblock") public ResponseEntity> unblockPartner( @RequestHeader("user-id") Long me, @PathVariable Long chatId @@ -131,4 +132,17 @@ public ResponseEntity> unblockPartner( BlockResponse res = chatService.unblockPartner(me, chatId); return ResponseEntity.ok(ApiResponse.onSuccess(res)); } + + @Operation(summary = "대화 상대 차단 여부 조회", description = "상대방을 차단 여부 조회.") + @GetMapping("/chats/{chatId}/block") + public ResponseEntity> getBlockStatus( + @RequestHeader("user-id") Long me, + @PathVariable Long chatId + ) { + BlockStatusResponse res = chatService.getBlockStatus(me, chatId); + return ResponseEntity.ok(ApiResponse.onSuccess(res)); + } + + + } diff --git a/src/main/java/com/salemale/domain/chat/dto/BlockStatusResponse.java b/src/main/java/com/salemale/domain/chat/dto/BlockStatusResponse.java new file mode 100644 index 0000000..42434ad --- /dev/null +++ b/src/main/java/com/salemale/domain/chat/dto/BlockStatusResponse.java @@ -0,0 +1,12 @@ +package com.salemale.domain.chat.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class BlockStatusResponse { + + private boolean iBlockedPartner; // 내가 상대를 차단했는지 + private boolean partnerBlockedMe; // 상대가 나를 차단했는지 +} diff --git a/src/main/java/com/salemale/domain/chat/dto/ChatDtos.java b/src/main/java/com/salemale/domain/chat/dto/ChatDtos.java index 54ff60f..ec9cb3b 100644 --- a/src/main/java/com/salemale/domain/chat/dto/ChatDtos.java +++ b/src/main/java/com/salemale/domain/chat/dto/ChatDtos.java @@ -25,8 +25,7 @@ public static class CreateChatRequest { private Long sellerId; // 판매자 ID private Long buyerId; // 구매자 ID } - - + /**채팅방 목록 : chatId + unreadCount */ @Getter @NoArgsConstructor @AllArgsConstructor @Builder @@ -51,6 +50,11 @@ public static class ChatSummaryResponse { //아이템 정보 추가 private ItemSummary item; + // 내가 이 대화 상대를 차단했는지 여부 + // true -> 이미 차단됨 + // false -> 차단 안 됨 + private boolean iBlockedPartner; + @Getter @NoArgsConstructor @AllArgsConstructor @Builder public static class Partner { private Long id; diff --git a/src/main/java/com/salemale/domain/chat/service/ChatService.java b/src/main/java/com/salemale/domain/chat/service/ChatService.java index 36886dc..cb83666 100644 --- a/src/main/java/com/salemale/domain/chat/service/ChatService.java +++ b/src/main/java/com/salemale/domain/chat/service/ChatService.java @@ -3,6 +3,7 @@ import com.salemale.domain.chat.dto.BlockResponse; import com.salemale.domain.chat.dto.ChatDtos.*; // DTO import com.salemale.domain.chat.dto.MessageDtos; +import com.salemale.domain.chat.dto.BlockStatusResponse; //차단 여부 import com.salemale.domain.chat.entity.Chat; // 채팅 엔티티 import com.salemale.domain.chat.entity.Message; //메시지 엔티티 import com.salemale.domain.chat.repository.ChatRepository; // 채팅 리포지토리 @@ -25,7 +26,9 @@ import java.time.LocalDateTime; import java.util.List; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import org.springframework.data.domain.Pageable; @@ -55,6 +58,11 @@ public List getChatSummaries(Long me, int page, int size) { List rows = chatRepository.findChatSummaries(me, offset, size); + // 내가 차단한 사용자 id 목록을 한 번에 조회 + List blockedUserIds = blockListRepository.findBlockedUserIds(me); + java.util.Set blockedSet = new java.util.HashSet<>(blockedUserIds); + + return rows.stream().map(r -> { // 대화 상대 ChatSummaryResponse.Partner partner = ChatSummaryResponse.Partner.builder() @@ -103,12 +111,16 @@ public List getChatSummaries(Long me, int page, int size) { .build(); } + // 내가 이 대화 상대를 차단했는지 여부 + boolean iBlockedPartner = blockedSet.contains(r.getPartnerId()); + return ChatSummaryResponse.builder() .chatId(r.getChatId()) .partner(partner) .lastMessage(last) .unreadCount(r.getUnreadCount() == null ? 0 : r.getUnreadCount()) .item(itemSummary) + .iBlockedPartner(iBlockedPartner) //차단 여부 추가 .build(); }).toList(); } @@ -294,15 +306,19 @@ public BlockResponse blockPartner(Long me, Long chatId) { Chat chat = chatRepository.findById(chatId) .orElseThrow(() -> new EntityNotFoundException("채팅방이 존재하지 않습니다.")); + if (!chat.getSeller().getId().equals(me) && !chat.getBuyer().getId().equals(me)) { + throw new IllegalStateException("대화 참여자가 아닙니다."); + } + Long partnerId = chat.getSeller().getId().equals(me) ? chat.getBuyer().getId() : chat.getSeller().getId(); - // 이미 차단된 경우 → blocked=false 로 반환 (프론트가 "이미 차단됨" UI 처리 가능) + // 이미 차단된 경우 if (blockListRepository.existsByBlocker_IdAndBlocked_Id(me, partnerId)) { return BlockResponse.builder() .blockedUserId(partnerId) - .blocked(false) + .blocked(true) .build(); } @@ -327,6 +343,12 @@ public BlockResponse unblockPartner(Long me, Long chatId) { Chat chat = chatRepository.findById(chatId) .orElseThrow(() -> new EntityNotFoundException("채팅방이 존재하지 않습니다.")); + // 참여자 검증(코드래빗 피드백) + if (!chat.getSeller().getId().equals(me) && !chat.getBuyer().getId().equals(me)) { + throw new IllegalStateException("대화 참여자가 아닙니다."); + } + + Long partnerId = chat.getSeller().getId().equals(me) ? chat.getBuyer().getId() : chat.getSeller().getId(); @@ -347,4 +369,28 @@ public BlockResponse unblockPartner(Long me, Long chatId) { .build(); } + @Transactional(readOnly = true) + public BlockStatusResponse getBlockStatus(Long me, Long chatId) { + + Chat chat = chatRepository.findById(chatId) + .orElseThrow(() -> new EntityNotFoundException("채팅방이 존재하지 않습니다.")); + + if (!chat.getSeller().getId().equals(me) && !chat.getBuyer().getId().equals(me)) { + throw new IllegalStateException("대화 참여자가 아닙니다."); + } + + Long partnerId = chat.getSeller().getId().equals(me) + ? chat.getBuyer().getId() + : chat.getSeller().getId(); + + boolean iBlockedPartner = + blockListRepository.existsByBlocker_IdAndBlocked_Id(me, partnerId); + + boolean partnerBlockedMe = + blockListRepository.existsByBlocker_IdAndBlocked_Id(partnerId, me); + + return new BlockStatusResponse(iBlockedPartner, partnerBlockedMe); + } + + }