From 003e8a9aaaa653cd1a769a35ac64d847d96143f7 Mon Sep 17 00:00:00 2001 From: rud15dns Date: Mon, 9 Feb 2026 22:50:40 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=EB=A9=A4=EB=B2=84=EC=8B=AD=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 16 ++++++++-------- .../server/domain/member/entity/Member.java | 9 +++++++++ .../domain/member/service/MemberService.java | 18 ++++++++++++++---- 3 files changed, 31 insertions(+), 12 deletions(-) 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 4f8adc5..25a18e2 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,12 +1,6 @@ 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; @@ -23,8 +17,6 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; -import java.util.List; - import static com.meetkey.server.domain.member.dto.MemberReqDTO.*; @RequiredArgsConstructor @@ -58,4 +50,12 @@ public ResponseEntity> blockMember( MemberResDTO.Block res = memberService.blockMember(fromMember.getMemberId(), toMemberId); return ResponseEntity.ok(BasicResponse.success(CommonSuccessStatus._OK, res)); } + + @PatchMapping("/membership") + public ResponseEntity> updateMembershipStatus( + @AuthenticationPrincipal CustomUserDetails details + ){ + memberService.updateMembershipStatus(details.getMemberId()); + return ResponseEntity.ok(BasicResponse.success(CommonSuccessStatus._OK, null)); + } } diff --git a/src/main/java/com/meetkey/server/domain/member/entity/Member.java b/src/main/java/com/meetkey/server/domain/member/entity/Member.java index 0c88056..8db6a2e 100644 --- a/src/main/java/com/meetkey/server/domain/member/entity/Member.java +++ b/src/main/java/com/meetkey/server/domain/member/entity/Member.java @@ -99,6 +99,15 @@ public int getAge() { return LocalDate.now().getYear() - this.birthday.getYear() + 1; } + public void updateMemberShip() { + if (this.membership == Membership.FREE) { + this.membership = Membership.PREMIUM; + } + else { + this.membership = Membership.FREE; + } + } + public void increaseRecommend() { this.recommendCount++; } 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 33ec965..134b9b8 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 @@ -78,13 +78,12 @@ 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)); + Member fromMember = findMemberById(fromId); + Member toMember = findMemberById(toId); FromToId blockId = new FromToId(fromId, toId); // 중복 차단인지 확인 @@ -106,6 +105,13 @@ public MemberResDTO.Block blockMember(Long fromId, Long toId){ .build(); } + @Transactional + public void updateMembershipStatus(Long memberId){ + Member member = findMemberById(memberId); + + member.updateMemberShip(); + } + // FCM 토큰 저장 @Transactional public void saveFcmToken(Long memberId, String token) { @@ -119,6 +125,10 @@ public void saveFcmToken(Long memberId, String token) { .token(token) .build()); } + } + public Member findMemberById(Long memberId) { + return memberRepository.findById(memberId) + .orElseThrow(() -> new MemberException(MemberErrorStatus.MEMBER_NOT_FOUND)); } } From 4356931fad207ea8105a269a1d8db818a86a51e4 Mon Sep 17 00:00:00 2001 From: rud15dns Date: Mon, 9 Feb 2026 23:41:30 +0900 Subject: [PATCH 2/3] =?UTF-8?q?fix:=20getProfile=20=EC=8B=9C=EC=97=90=20s3?= =?UTF-8?q?=20image=20url=EB=8F=84=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/ProfileController.java | 2 +- .../domain/member/converter/ProfileConverter.java | 10 ++++++---- .../meetkey/server/domain/member/entity/Member.java | 5 +++++ .../server/domain/member/service/ProfileService.java | 10 ++++++++-- .../java/com/meetkey/server/global/s3/S3Service.java | 4 ++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java b/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java index cc0ce60..3e8048f 100644 --- a/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java +++ b/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java @@ -226,7 +226,7 @@ public BasicResponse registerMemberPhotos( return BasicResponse.success(CommonSuccessStatus._OK, null); } - @Operation(summary = "내 프로필 사진 조회 API", description = "로그인한 사용자의 프로필 사진 URL 리스트를 가져옵니다.") + @Operation(summary = "내 프로필 사진 조회 API", description = "로그인한 사용자의 모든 프로필 사진 URL 리스트를 가져옵니다.") @GetMapping("/photos") public BasicResponse> getMyPhotos( @AuthenticationPrincipal CustomUserDetails customUserDetails diff --git a/src/main/java/com/meetkey/server/domain/member/converter/ProfileConverter.java b/src/main/java/com/meetkey/server/domain/member/converter/ProfileConverter.java index 62a556b..917d450 100644 --- a/src/main/java/com/meetkey/server/domain/member/converter/ProfileConverter.java +++ b/src/main/java/com/meetkey/server/domain/member/converter/ProfileConverter.java @@ -123,7 +123,8 @@ public MyProfileResponse toProfileResponse( Member member, List interests, Preference personality, - BadgeResponse badge + BadgeResponse badge, + String profileUrl ) { List interestNames = interests.stream() .map(interest -> interest.getType().name()) @@ -135,7 +136,7 @@ public MyProfileResponse toProfileResponse( .first(member.getFirstLanguage()) .target(member.getTargetLanguage()) .age(member.getAge()) - .profileImage("image") + .profileImage(profileUrl) .recommendCount(member.getRecommendCount()) .notRecommendCount(member.getNotRecommendCount()) .badge(badge) @@ -151,7 +152,8 @@ public OtherProfileResponse toOtherProfileResponse( List interests, Preference personality, String distance, - BadgeResponse badge + BadgeResponse badge, + String profileUrl ) { List interestNames = interests.stream() .map(interest -> interest.getType().name()) @@ -163,7 +165,7 @@ public OtherProfileResponse toOtherProfileResponse( .age(member.getAge()) .gender(member.getGender()) .homeTown(member.getHomeTown()) - .profileImage("image") + .profileImage(profileUrl) .location(member.getLocation()) .distance(distance) .recommendCount(member.getRecommendCount()) diff --git a/src/main/java/com/meetkey/server/domain/member/entity/Member.java b/src/main/java/com/meetkey/server/domain/member/entity/Member.java index 8db6a2e..996b7f4 100644 --- a/src/main/java/com/meetkey/server/domain/member/entity/Member.java +++ b/src/main/java/com/meetkey/server/domain/member/entity/Member.java @@ -1,6 +1,7 @@ package com.meetkey.server.domain.member.entity; import com.meetkey.server.domain.member.entity.mapping.InterestMember; +import com.meetkey.server.domain.member.entity.mapping.MemberPhoto; import com.meetkey.server.domain.member.enums.*; import com.meetkey.server.global.common.BaseEntity; import jakarta.persistence.*; @@ -99,6 +100,10 @@ public int getAge() { return LocalDate.now().getYear() - this.birthday.getYear() + 1; } + public void updateProfilePhotoUrl(String profilePhotoUrl) { + this.profileImageUrl = profilePhotoUrl; + } + public void updateMemberShip() { if (this.membership == Membership.FREE) { this.membership = Membership.PREMIUM; diff --git a/src/main/java/com/meetkey/server/domain/member/service/ProfileService.java b/src/main/java/com/meetkey/server/domain/member/service/ProfileService.java index 0ddf9a7..8b67806 100644 --- a/src/main/java/com/meetkey/server/domain/member/service/ProfileService.java +++ b/src/main/java/com/meetkey/server/domain/member/service/ProfileService.java @@ -13,6 +13,7 @@ import com.meetkey.server.domain.member.exception.MemberErrorStatus; import com.meetkey.server.domain.member.exception.MemberException; import com.meetkey.server.domain.member.repository.*; +import com.meetkey.server.global.s3.S3Service; import lombok.RequiredArgsConstructor; import org.jetbrains.annotations.Nullable; import org.springframework.stereotype.Service; @@ -39,6 +40,7 @@ public class ProfileService { private final EvaluationRepository evaluationRepository; private final BadgeService badgeService; private final GeocodingService geocodingService; + private final S3Service s3Service; public ProfileUpdateResponse updateProfile(Long memberId, ProfileUpdateRequest request) { Member member = getMember(memberId); @@ -161,7 +163,9 @@ public MyProfileResponse getMyProfile(Long memberId) { .map(InterestMember::getInterest) .toList(); - return profileConverter.toProfileResponse(member, interests, preference, badge); + String profileImageUrl = s3Service.generateGetPresignedUrl(member.getProfileImageUrl()); + + return profileConverter.toProfileResponse(member, interests, preference, badge, profileImageUrl); } // 다른 사람 프로필 조회 @@ -185,7 +189,9 @@ public OtherProfileResponse getOtherProfile(Long memberId, Long targetMemberId) .map(InterestMember::getInterest) .toList(); - return profileConverter.toOtherProfileResponse(target, interests, preference, distance, badge); + String profileImageUrl = s3Service.generateGetPresignedUrl(target.getProfileImageUrl()); + + return profileConverter.toOtherProfileResponse(target, interests, preference, distance, badge, profileImageUrl); } diff --git a/src/main/java/com/meetkey/server/global/s3/S3Service.java b/src/main/java/com/meetkey/server/global/s3/S3Service.java index 5d23737..e1f520e 100644 --- a/src/main/java/com/meetkey/server/global/s3/S3Service.java +++ b/src/main/java/com/meetkey/server/global/s3/S3Service.java @@ -109,6 +109,10 @@ public void registerMemberPhotoKeys(Long memberId, List s3Keys){ .collect(Collectors.toList()); memberPhotoRepository.saveAll(photos); + + if (!s3Keys.isEmpty()) { + member.updateProfilePhotoUrl(s3Keys.get(0)); + } } From 0e6a9d3b9e2ce2f41b86d406c2be70221c67a9fe Mon Sep 17 00:00:00 2001 From: rud15dns Date: Mon, 9 Feb 2026 23:42:56 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20=EA=B8=B0=EB=8A=A5=20=EB=AA=85?= =?UTF-8?q?=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/domain/member/controller/ProfileController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java b/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java index 3e8048f..2f41536 100644 --- a/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java +++ b/src/main/java/com/meetkey/server/domain/member/controller/ProfileController.java @@ -214,6 +214,7 @@ public BasicResponse> getMemberPhotoUploadUrl return BasicResponse.success(CommonSuccessStatus._OK, responses); } + @Operation(summary = "프로필 key 저장 API", description = "앞선 요청으로 받은 프로필 key들을 DB에 저장합니다. ") @PostMapping("/photos/register") public BasicResponse registerMemberPhotos( @AuthenticationPrincipal CustomUserDetails customUserDetails, @@ -226,7 +227,7 @@ public BasicResponse registerMemberPhotos( return BasicResponse.success(CommonSuccessStatus._OK, null); } - @Operation(summary = "내 프로필 사진 조회 API", description = "로그인한 사용자의 모든 프로필 사진 URL 리스트를 가져옵니다.") + @Operation(summary = "내 프로필 사진 전체 조회 API", description = "로그인한 사용자의 모든 프로필 사진 URL 리스트를 가져옵니다.") @GetMapping("/photos") public BasicResponse> getMyPhotos( @AuthenticationPrincipal CustomUserDetails customUserDetails