From 1a2b0c64b95f974e0c5921e0149f1e6a78ca906e Mon Sep 17 00:00:00 2001 From: rud15dns Date: Mon, 9 Feb 2026 21:13:35 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=82=AC=EC=9A=A9=EC=9E=90=20=EC=B0=A8?= =?UTF-8?q?=EB=8B=A8=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84=20=EB=B0=8F?= =?UTF-8?q?=20=EC=8B=A0=EA=B3=A0=20=EC=8B=9C=20=EC=B0=A8=EB=8B=A8=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 25 ++++++++++++--- .../domain/member/dto/MemberResDTO.java | 13 ++++++++ .../member/entity/mapping/FromToId.java | 2 ++ .../member/entity/mapping/MemberBlock.java | 6 ++-- .../member/exception/MemberErrorStatus.java | 3 +- .../repository/MemberBlockRepository.java | 20 ++++++++++++ .../domain/member/service/MemberService.java | 32 +++++++++++++++++++ .../report/controller/ReportController.java | 4 +++ 8 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/meetkey/server/domain/member/dto/MemberResDTO.java create mode 100644 src/main/java/com/meetkey/server/domain/member/repository/MemberBlockRepository.java diff --git a/src/main/java/com/meetkey/server/domain/member/controller/MemberController.java b/src/main/java/com/meetkey/server/domain/member/controller/MemberController.java index 6ce5381..4f8adc5 100644 --- a/src/main/java/com/meetkey/server/domain/member/controller/MemberController.java +++ b/src/main/java/com/meetkey/server/domain/member/controller/MemberController.java @@ -1,7 +1,14 @@ package com.meetkey.server.domain.member.controller; import com.meetkey.server.domain.member.dto.MemberReqDTO; +import com.meetkey.server.domain.member.dto.MemberResDTO; import com.meetkey.server.domain.member.dto.ProfileResDTO; +import com.meetkey.server.domain.member.entity.Member; +import com.meetkey.server.domain.member.entity.mapping.MemberBlock; +import com.meetkey.server.domain.member.exception.MemberErrorStatus; +import com.meetkey.server.domain.member.exception.MemberException; +import com.meetkey.server.domain.member.repository.MemberBlockRepository; +import com.meetkey.server.domain.member.repository.MemberRepository; import com.meetkey.server.domain.member.service.MemberService; import com.meetkey.server.global.apiPayload.response.BasicResponse; import com.meetkey.server.global.apiPayload.status.CommonSuccessStatus; @@ -14,10 +21,9 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; import static com.meetkey.server.domain.member.dto.MemberReqDTO.*; @@ -27,6 +33,8 @@ public class MemberController { private final MemberService memberService; + private final MemberRepository memberRepository; + private final MemberBlockRepository memberBlockRepository; @Operation(summary = "FCM 토큰 저장 API", description = "사용자의 FCM 토큰을 저장합니다. (앱이 켜지거나 로그인시에 호출)") @ApiResponses(value = { @@ -41,4 +49,13 @@ public ResponseEntity> saveFcmToken( memberService.saveFcmToken(userDetails.getMemberId(), request.token()); return ResponseEntity.ok(BasicResponse.success(CommonSuccessStatus._OK, "토큰 저장 완료")); } + + @PostMapping("/block/{memberId}") + public ResponseEntity> blockMember( + @AuthenticationPrincipal CustomUserDetails fromMember, + @PathVariable("memberId") Long toMemberId + ){ + MemberResDTO.Block res = memberService.blockMember(fromMember.getMemberId(), toMemberId); + return ResponseEntity.ok(BasicResponse.success(CommonSuccessStatus._OK, res)); + } } diff --git a/src/main/java/com/meetkey/server/domain/member/dto/MemberResDTO.java b/src/main/java/com/meetkey/server/domain/member/dto/MemberResDTO.java new file mode 100644 index 0000000..21c72db --- /dev/null +++ b/src/main/java/com/meetkey/server/domain/member/dto/MemberResDTO.java @@ -0,0 +1,13 @@ +package com.meetkey.server.domain.member.dto; + +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +public class MemberResDTO { + + @Builder + public record Block( + @NotNull Long fromMemberId, + @NotNull Long toMemberId + ){} +} diff --git a/src/main/java/com/meetkey/server/domain/member/entity/mapping/FromToId.java b/src/main/java/com/meetkey/server/domain/member/entity/mapping/FromToId.java index a37e827..515c53f 100644 --- a/src/main/java/com/meetkey/server/domain/member/entity/mapping/FromToId.java +++ b/src/main/java/com/meetkey/server/domain/member/entity/mapping/FromToId.java @@ -4,9 +4,11 @@ import jakarta.persistence.Embeddable; import lombok.AccessLevel; import lombok.EqualsAndHashCode; +import lombok.Getter; import lombok.NoArgsConstructor; @Embeddable +@Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @EqualsAndHashCode public class FromToId { diff --git a/src/main/java/com/meetkey/server/domain/member/entity/mapping/MemberBlock.java b/src/main/java/com/meetkey/server/domain/member/entity/mapping/MemberBlock.java index 88c7605..f48688e 100644 --- a/src/main/java/com/meetkey/server/domain/member/entity/mapping/MemberBlock.java +++ b/src/main/java/com/meetkey/server/domain/member/entity/mapping/MemberBlock.java @@ -3,15 +3,13 @@ import com.meetkey.server.domain.member.entity.Member; import com.meetkey.server.global.common.BaseEntity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor(access = AccessLevel.PRIVATE) +@Builder @Table(name = "member_block") public class MemberBlock extends BaseEntity { @EmbeddedId diff --git a/src/main/java/com/meetkey/server/domain/member/exception/MemberErrorStatus.java b/src/main/java/com/meetkey/server/domain/member/exception/MemberErrorStatus.java index 5d875bf..4a4ae53 100644 --- a/src/main/java/com/meetkey/server/domain/member/exception/MemberErrorStatus.java +++ b/src/main/java/com/meetkey/server/domain/member/exception/MemberErrorStatus.java @@ -17,7 +17,8 @@ public enum MemberErrorStatus implements BaseCode { // 회원 관련 MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "MEMBER4041", "해당 사용자를 찾을 수 없습니다."), - INVALID_S3_KEY(HttpStatus.NOT_FOUND, "MEMBER4042", "저장된 프로필 사진을 찾을 수 없습니다."); + INVALID_S3_KEY(HttpStatus.NOT_FOUND, "MEMBER4042", "저장된 프로필 사진을 찾을 수 없습니다."), + ALREADY_BLOCKED(HttpStatus.BAD_REQUEST, "MEMBER_4001", "이미 차단된 사용자입니다.") ; private final HttpStatus status; diff --git a/src/main/java/com/meetkey/server/domain/member/repository/MemberBlockRepository.java b/src/main/java/com/meetkey/server/domain/member/repository/MemberBlockRepository.java new file mode 100644 index 0000000..c141d7c --- /dev/null +++ b/src/main/java/com/meetkey/server/domain/member/repository/MemberBlockRepository.java @@ -0,0 +1,20 @@ +package com.meetkey.server.domain.member.repository; + +import com.meetkey.server.domain.member.entity.mapping.FromToId; +import com.meetkey.server.domain.member.entity.mapping.MemberBlock; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface MemberBlockRepository extends JpaRepository { + // fromId가 toId를 차단했는지를 알 수 있는 메소드 + // ex) existsByMemberBlockIdFromIdAndMemberBlockIdToId(myId, targetId) + boolean existsByMemberBlockIdFromIdAndMemberBlockIdToId(Long fromId, Long toId); + + // 내가 누구를 차단했는지 + // ex) List l = memberBlockRepository.findAllByMemberBlockIdFromId(1L); + // for (MemberBlock mb : l){ + // System.out.println(mb.getToMember().getId()); + // } + List findAllByMemberBlockIdFromId(Long fromId); +} \ No newline at end of file diff --git a/src/main/java/com/meetkey/server/domain/member/service/MemberService.java b/src/main/java/com/meetkey/server/domain/member/service/MemberService.java index e7d4079..33ec965 100644 --- a/src/main/java/com/meetkey/server/domain/member/service/MemberService.java +++ b/src/main/java/com/meetkey/server/domain/member/service/MemberService.java @@ -2,13 +2,17 @@ import com.meetkey.server.domain.member.dto.MemberReqDTO; +import com.meetkey.server.domain.member.dto.MemberResDTO; import com.meetkey.server.domain.member.entity.Member; import com.meetkey.server.domain.member.entity.SocialLogin; import com.meetkey.server.domain.member.entity.mapping.FcmToken; +import com.meetkey.server.domain.member.entity.mapping.FromToId; +import com.meetkey.server.domain.member.entity.mapping.MemberBlock; import com.meetkey.server.domain.member.enums.Provider; import com.meetkey.server.domain.member.enums.Role; import com.meetkey.server.domain.member.exception.MemberErrorStatus; import com.meetkey.server.domain.member.exception.MemberException; +import com.meetkey.server.domain.member.repository.MemberBlockRepository; import com.meetkey.server.domain.member.repository.MemberRepository; import com.meetkey.server.domain.member.repository.SocialLoginRepository; import com.meetkey.server.domain.notification.repository.FcmTokenRepository; @@ -22,6 +26,7 @@ public class MemberService { private final MemberRepository memberRepository; private final SocialLoginRepository socialLoginRepository; private final FcmTokenRepository fcmTokenRepository; + private final MemberBlockRepository memberBlockRepository; @Transactional public Member signup(Provider provider, String providerId, MemberReqDTO.Signup req) { @@ -73,6 +78,33 @@ public Member devSignup(Provider provider, String providerId, MemberReqDTO.Signu return member; } + @Transactional + public MemberResDTO.Block blockMember(Long fromId, Long toId){ + // 멤버 있는지 없는지 확인 + Member fromMember = memberRepository.findById(fromId) + .orElseThrow(() -> new MemberException(MemberErrorStatus.MEMBER_NOT_FOUND)); + Member toMember = memberRepository.findById(toId) + .orElseThrow(() -> new MemberException(MemberErrorStatus.MEMBER_NOT_FOUND)); + FromToId blockId = new FromToId(fromId, toId); + + // 중복 차단인지 확인 + if (memberBlockRepository.existsById(blockId)) { + throw new MemberException(MemberErrorStatus.ALREADY_BLOCKED); + } + + MemberBlock memberBlock = MemberBlock.builder() + .memberBlockId(blockId) + .fromMember(fromMember) + .toMember(toMember) + .build(); + + memberBlockRepository.save(memberBlock); + + return MemberResDTO.Block.builder() + .fromMemberId(fromId) + .toMemberId(toId) + .build(); + } // FCM 토큰 저장 @Transactional diff --git a/src/main/java/com/meetkey/server/domain/report/controller/ReportController.java b/src/main/java/com/meetkey/server/domain/report/controller/ReportController.java index c418475..17079ce 100644 --- a/src/main/java/com/meetkey/server/domain/report/controller/ReportController.java +++ b/src/main/java/com/meetkey/server/domain/report/controller/ReportController.java @@ -1,5 +1,6 @@ package com.meetkey.server.domain.report.controller; +import com.meetkey.server.domain.member.service.MemberService; import com.meetkey.server.domain.report.dto.ReportReqDTO; import com.meetkey.server.domain.report.service.ReportService; import com.meetkey.server.global.apiPayload.response.BasicResponse; @@ -15,6 +16,7 @@ @RequestMapping("/report") public class ReportController { private final ReportService reportService; + private final MemberService memberService; @PostMapping("/{targetId}") public ResponseEntity> createReport( @@ -23,6 +25,8 @@ public ResponseEntity> createReport( @RequestBody ReportReqDTO.CreateReport req ) { reportService.createReport(reporter.getMemberId(), targetId, req); + memberService.blockMember(reporter.getMemberId(), targetId); + return ResponseEntity.ok() .body(BasicResponse.success(CommonSuccessStatus._OK, null)); }