Skip to content

Commit

Permalink
feat: 프로필 이미지 추가/변경, 프로필 불러오기
Browse files Browse the repository at this point in the history
  • Loading branch information
do-dop committed Feb 14, 2025
1 parent aecec1a commit 31df73e
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/main/java/PATATA/auth/oauth/service/OAuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import PATATA.auth.oauth.dto.*;
import PATATA.domain.member.entity.LoginType;
import PATATA.domain.member.entity.Role;
import PATATA.global.error.code.status.ErrorStatus;
import PATATA.global.error.exception.MemberHandler;
import PATATA.global.error.exception.OAuthHandler;
Expand Down Expand Up @@ -89,6 +90,9 @@ public LoginResponseDTO appleLogin(AppleLoginRequestDTO appleLoginRequestDto) {
//이메일 중복인 경우
Member member = memberByEmail.get();
LoginType loginType = member.getLoginType();
if (member.getRole() == Role.WITHDRAWAL) {
throw new MemberHandler(MEMBER_ALREADY_WITHDRAW);
}
if (!loginType.equals(LoginType.APPLE)) {
throw new MemberHandler("이미 " + loginType + "으로 가입한 회원입니다.");
}
Expand Down Expand Up @@ -138,6 +142,9 @@ public LoginResponseDTO googleLogin(GoogleLoginRequestDTO googleReqDto) {
if (memberByEmail.isPresent()) {
Member member = memberByEmail.get();
LoginType loginType = member.getLoginType();
if (member.getRole() == Role.WITHDRAWAL) {
throw new MemberHandler(MEMBER_ALREADY_WITHDRAW);
}
if (!loginType.equals(LoginType.GOOGLE)) {
throw new MemberHandler("이미 " + loginType + "으로 가입한 회원입니다.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package PATATA.domain.member.controller;

import PATATA.domain.member.dto.MemberProfileDto;
import PATATA.domain.member.dto.NickNameDto;
import PATATA.domain.member.entity.Member;
import PATATA.domain.member.service.MemberService;
import PATATA.global.response.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PatchMapping;
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 org.springframework.web.multipart.MultipartFile;

@RestController
@RequestMapping("/member")
Expand All @@ -30,4 +31,23 @@ public ApiResponse<Void> updateNickname(
memberService.updateNickname(member, nickNameDto.getNickName());
return ApiResponse.onSuccess(null);
}

@Operation(summary = "프로필 이미지 추가/변경")
@PatchMapping(value = "/profileImage", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ApiResponse<String> updateProfileImage(
@AuthenticationPrincipal Member member,
@RequestPart("profileImage") MultipartFile profileImage
) {
String image = memberService.updateProfileImage(member, profileImage);
return ApiResponse.onSuccess(image);
}

@Operation(summary = "프로필 불러오기")
@GetMapping("/profile")
public ApiResponse<MemberProfileDto> getProfile(
@AuthenticationPrincipal Member member
) {
MemberProfileDto profileDto = memberService.getProfile(member);
return ApiResponse.onSuccess(profileDto);
}
}
24 changes: 24 additions & 0 deletions src/main/java/PATATA/domain/member/dto/MemberProfileDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package PATATA.domain.member.dto;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class MemberProfileDto {

private Long memberId;
private String nickName;
private String email;
private String profileImage;

@Builder
public MemberProfileDto(Long memberId, String nickName, String email, String profileImage) {
this.memberId = memberId;
this.nickName = nickName;
this.email = email;
this.profileImage = profileImage;
}
}
6 changes: 6 additions & 0 deletions src/main/java/PATATA/domain/member/entity/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public void updateRole(Role role) {
this.role = role;
}

private String profileImage;

private String nickName;

private String email;
Expand Down Expand Up @@ -101,4 +103,8 @@ public boolean isEnabled() {
public void updateNickname(String newNickname) {
this.nickName = newNickname;
}

public void updateImage(String imageUrl) {
this.profileImage = imageUrl;
}
}
35 changes: 35 additions & 0 deletions src/main/java/PATATA/domain/member/service/MemberService.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
package PATATA.domain.member.service;

import PATATA.domain.member.dto.MemberProfileDto;
import PATATA.domain.member.entity.Role;
import PATATA.domain.spot.entity.Review;
import PATATA.domain.spot.entity.Scrap;
import PATATA.domain.spot.entity.Spot;
import PATATA.domain.spot.repository.ReviewRepository;
import PATATA.domain.spot.repository.ScrapRepository;
import PATATA.domain.spot.repository.SpotRepository;
import PATATA.domain.spot.service.S3ImageService;
import PATATA.global.error.exception.JwtHandler;
import PATATA.global.error.exception.MemberHandler;
import PATATA.auth.jwt.service.JwtService;
import PATATA.domain.member.entity.Member;
import PATATA.domain.member.repository.MemberRepository;
import PATATA.auth.oauth.dto.LoginResponseDTO;
import PATATA.global.error.exception.S3ImageHandler;
import PATATA.global.error.exception.SpotHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

Expand All @@ -31,6 +36,7 @@ public class MemberService {
private final SpotRepository spotRepository;
private final ReviewRepository reviewRepository;
private final ScrapRepository scrapRepository;
private final S3ImageService s3ImageService;

//accessToken, refreshToken 발급
@Transactional
Expand Down Expand Up @@ -89,6 +95,7 @@ public void updateNickname(Member member, String newNickname) {
memberRepository.save(member);
}

@Transactional
public void deleteMember(Member member) {
//스팟 삭제
deleteSpot(member);
Expand All @@ -98,6 +105,7 @@ public void deleteMember(Member member) {
deleteScrap(member);
//멤버 역할 변경
member.updateRole(Role.WITHDRAWAL);
memberRepository.save(member);
}

private void deleteSpot(Member member) {
Expand All @@ -117,4 +125,31 @@ private void deleteScrap(Member member) {
scraps.forEach(Scrap::delete);
scrapRepository.saveAll(scraps);
}

@Transactional
public String updateProfileImage(Member member, MultipartFile profileImage) {
if (profileImage.isEmpty()) {
throw new S3ImageHandler(IMAGE_EMPTY);
}
try {
String imageUrl = s3ImageService.upload(profileImage);
member.updateImage(imageUrl);
memberRepository.save(member);
return imageUrl;
} catch (Exception e) {
throw new SpotHandler(S3_UPLOAD_FAIL);
}
}

public MemberProfileDto getProfile(Member member) {

MemberProfileDto profileDto = MemberProfileDto.builder()
.memberId(member.getMemberId())
.nickName(member.getNickName())
.email(member.getEmail())
.profileImage(member.getProfileImage())
.build();

return profileDto;
}
}
6 changes: 3 additions & 3 deletions src/main/java/PATATA/domain/spot/dto/SpotResponseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ public static DetailResponse from(Spot spot, Boolean isAuthor, Boolean isScraped
.map(review -> ReviewInfo.builder()
.reviewId(review.getReviewId())
.reviewText(review.getReviewText())
.memberName(review.getMember().getNickName())
.memberName(review.getMember() != null ? review.getMember().getNickName() : "알 수 없음")
.reviewDate(review.getCreatedAt())
.isAuthor(review.getMember().getMemberId().equals(member.getMemberId()))
.isAuthor(review.getMember() != null && review.getMember().getMemberId().equals(member.getMemberId()))
.build())
.collect(Collectors.toList());

Expand All @@ -85,7 +85,7 @@ public static DetailResponse from(Spot spot, Boolean isAuthor, Boolean isScraped
.spotAddress(spot.getSpotAddress())
.spotAddressDetail(spot.getSpotAddressDetail())
.categoryId(spot.getSpotCategory().getCategoryId())
.memberName(spot.getMember().getNickName())
.memberName(spot.getMember() != null ? spot.getMember().getNickName() : "알 수 없음")
.images(images)
.tags(tagNames)
.reviewCount(reviewInfos.size())
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/PATATA/domain/spot/service/SpotService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import PATATA.domain.spot.entity.*;
import PATATA.domain.spot.repository.*;
import PATATA.global.error.exception.ReportHandler;
import PATATA.global.error.exception.S3ImageHandler;
import PATATA.global.error.exception.SpotHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -77,7 +78,7 @@ private Point createPoint(Double longitude, Double latitude) {

private void processSpotImages(List<SpotRequestDto.SpotImageRequest> images, Spot spot) {
if (images == null || images.isEmpty()) {
return;
throw new S3ImageHandler(IMAGE_EMPTY);
}

List<SpotImage> spotImages = images.stream()
Expand Down Expand Up @@ -126,7 +127,8 @@ private void processSpotTags(List<String> tags, Spot spot) {
public SpotResponseDto.DetailResponse getSpotDetail(Long spotId, Member member) {
Spot spot = spotRepository.findByIdAndDeletedFalse(spotId)
.orElseThrow(() -> new SpotHandler(SPOT_NOT_FOUND));
Boolean isAuthor = spot.getMember().getMemberId().equals(member.getMemberId());
Boolean isAuthor = spot.getMember() != null && spot.getMember().getMemberId().equals(member.getMemberId());

Boolean isScraped = scrapRepository.existsByMemberAndSpotAndDeletedFalse(member, spot);
List<Review> reviews = reviewRepository.findBySpot(spot);
List<Tag> tags = spotTagRepository.findBySpot(spot).stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public enum ErrorStatus implements BaseErrorCode {
NICKNAME_ALREADY_EXIST(HttpStatus.BAD_REQUEST, "MEMBER4001", "이미 사용중인 닉네임입니다."),
MEMBER_NOT_MATCH(HttpStatus.BAD_REQUEST, "MEMBER4002", "사용자가 일치하지 않습니다."),
MEMBER_DELETE_FAILED(HttpStatus.BAD_REQUEST, "MEMBER4003", "회원 탈퇴에 실패하였습니다."),
MEMBER_ALREADY_WITHDRAW(HttpStatus.BAD_REQUEST, "MEMBER4004", "탈퇴한 회원입니다."),

//Spot 에러
SPOT_NOT_FOUND(HttpStatus.BAD_REQUEST, "SPOT4000", "삭제되었거나 존재하지 않는 스팟입니다."),
Expand Down

0 comments on commit 31df73e

Please sign in to comment.