Skip to content

Commit

Permalink
Merge pull request #30 from Team-baebae/feature/member/#29
Browse files Browse the repository at this point in the history
Feature/member/#29
  • Loading branch information
tioon authored May 3, 2024
2 parents 8a3d2fb + 5050f2e commit 802cc92
Show file tree
Hide file tree
Showing 15 changed files with 731 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.web.baebaeBE.application.manage.member;

import com.web.baebaeBE.domain.manage.member.service.ManageMemberService;
import com.web.baebaeBE.global.jwt.JwtTokenProvider;
import com.web.baebaeBE.infra.member.entity.Member;
import com.web.baebaeBE.presentation.manage.member.dto.ManageMemberRequest;
import com.web.baebaeBE.presentation.manage.member.dto.ManageMemberResponse;
import jakarta.servlet.http.HttpServletRequest;
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;

@Service
@Slf4j
@Transactional
@RequiredArgsConstructor
public class ManageMemberApplication {

private final ManageMemberService manageMemberService;
private final JwtTokenProvider jwtTokenProvider;

public ManageMemberResponse.MemberInformationResponse getMember(Long memberId) {
return manageMemberService.getMember(memberId);
}

public ManageMemberResponse.ObjectUrlResponse updateProfileImage(Long memberId, MultipartFile image) {
String fileKey = manageMemberService.convertImageToObject(memberId, image);
manageMemberService.updateProfileImage(memberId, fileKey);
return ManageMemberResponse.ObjectUrlResponse.of(fileKey);
}

public void updateFcmToken(Long memberId, ManageMemberRequest.UpdateFcmTokenDto updateFcmTokenDto) {
manageMemberService.updateFcmToken(memberId, updateFcmTokenDto.getFcmToken());
}

public void updateNickname(Long memberId, ManageMemberRequest.UpdateNicknameDto updateNicknameDto) {
manageMemberService.updateNickname(memberId, updateNicknameDto.getNickname());
}

public void deleteMember(Long memberId, HttpServletRequest httpServletRequest) {
String accessToken = jwtTokenProvider.getToken(httpServletRequest);
manageMemberService.verifyMemberWithToken(memberId, accessToken);
manageMemberService.deleteMember(memberId);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.web.baebaeBE.domain.manage.member.exception;

import com.web.baebaeBE.global.error.ErrorCode;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;


@Getter
@RequiredArgsConstructor
public enum ManageMemberError implements ErrorCode {
NOT_EXIST_MEMBER(HttpStatus.NOT_FOUND, "MM-001", "존재하지 않는 회원입니다."),
NOT_VERIFY_MEMBET_WITH_TOKEN(HttpStatus.UNAUTHORIZED,"MM-002", "회원정보와 토큰정보가 일치하지 않습니다.");


private final HttpStatus httpStatus;
private final String errorCode;
private final String message;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.web.baebaeBE.domain.manage.member.service;

import com.web.baebaeBE.domain.manage.member.exception.ManageMemberError;
import com.web.baebaeBE.domain.member.exception.MemberError;
import com.web.baebaeBE.global.error.exception.BusinessException;
import com.web.baebaeBE.global.jwt.JwtTokenProvider;
import com.web.baebaeBE.infra.member.entity.Member;
import com.web.baebaeBE.infra.member.repository.MemberRepository;
import com.web.baebaeBE.presentation.manage.member.dto.ManageMemberResponse;
import com.web.baebaeBE.presentation.member.dto.MemberResponse;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
@RequiredArgsConstructor
@Slf4j
public class ManageMemberService {

private final MemberRepository memberRepository;
private final JwtTokenProvider jwtTokenProvider;

public ManageMemberResponse.MemberInformationResponse getMember(Long memberId) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(MemberError.NOT_EXIST_MEMBER));

return ManageMemberResponse.MemberInformationResponse.of(member);
}

public void updateProfileImage(Long memberId, String profileImage) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(MemberError.NOT_EXIST_MEMBER));

member.updateProfileImage(profileImage);
memberRepository.save(member);
}

// 이미지 파일을 Object Storage에 저장하고 키파일을 반환하는 메서드
// 추후 수정할 예정
public String convertImageToObject(Long memberId, MultipartFile image){
return image.getName();
}

public void updateFcmToken(Long memberId, String fcmToken) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(MemberError.NOT_EXIST_MEMBER));

member.updateFcmToken(fcmToken);
memberRepository.save(member);
}

public void updateNickname(Long memberId, String nickname) {
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(MemberError.NOT_EXIST_MEMBER));

member.update(nickname);
memberRepository.save(member);
}

public void deleteMember(Long id) {
memberRepository.deleteById(id);
}

public void verifyMemberWithToken(Long memberId,String accessToken){
Member member = memberRepository.findById(memberId)
.orElseThrow(() -> new BusinessException(MemberError.NOT_EXIST_MEMBER));

String memberEmail = jwtTokenProvider.getUserEmail(accessToken);

//회원 정보와 토큰안의 이메일 정보가 일치하지않으면 예외 발생
if(!member.getEmail().equals(memberEmail))
throw new BusinessException(ManageMemberError.NOT_VERIFY_MEMBET_WITH_TOKEN);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Date;
import java.util.Set;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down Expand Up @@ -89,6 +90,9 @@ public Authentication getAuthentication(String token) {
(), "", authorities), token, authorities);
}

public String getToken(HttpServletRequest httpServletRequest){
return httpServletRequest.getHeader("Authorization").substring(7);
}

//토큰에서 사용자 ID 가져오는 메서드
public String getUserEmail(String token) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.web.baebaeBE.global.util;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;

@Component
public class MultipartJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {

protected MultipartJackson2HttpMessageConverter(ObjectMapper objectMapper) {
super(objectMapper, MediaType.APPLICATION_OCTET_STREAM);
}

@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType){
return false;
}

@Override
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType){
return false;
}

@Override
protected boolean canWrite(MediaType mediaType){
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class Member implements UserDetails {

private String nickname;

@Column(name="profile_image")
private String profileImage;

@Column(name = "member_type", nullable = false)
@Enumerated(EnumType.STRING)
private MemberType memberType;
Expand All @@ -49,6 +52,9 @@ public class Member implements UserDetails {
@Column(name = "token_expiration_time")
private LocalDateTime tokenExpirationTime;

@Column(name = "fcm_token")
private String fcmToken;


public Member update(String nickname) {
this.nickname = nickname;
Expand All @@ -58,6 +64,13 @@ public Member update(String nickname) {
public void updateRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public void updateProfileImage(String profileImageKey){
this.profileImage = profileImageKey;
}
public void updateFcmToken(String fcmToken){
this.fcmToken = fcmToken;
}


public void updateTokenExpirationTime(LocalDateTime time) {
this.tokenExpirationTime = time;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.web.baebaeBE.presentation.healthcheck;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Tag(name = "Health Check", description = "헬스체크용 API")
public class HealthCheckController {

@GetMapping("/healthcheck")
@Operation(summary = "Health Check", description = "Load Balncer용 API입니다. (사용X)",
responses = {
@ApiResponse(responseCode = "200", description = "서버 상태 정상")
})
public String healthCheck() {
return "OK"; // 서버가 정상적으로 작동 중임을 의미
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.web.baebaeBE.presentation.manage.member;


import com.web.baebaeBE.application.manage.member.ManageMemberApplication;
import com.web.baebaeBE.presentation.manage.member.api.ManageMemberApi;
import com.web.baebaeBE.presentation.manage.member.dto.ManageMemberRequest;
import com.web.baebaeBE.presentation.manage.member.dto.ManageMemberResponse;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


@RestController
@RequiredArgsConstructor
@RequestMapping("/api/member")
public class ManageMemberController implements ManageMemberApi {


private final ManageMemberApplication manageMemberApplication;


@GetMapping("/{memberId}")
public ResponseEntity<ManageMemberResponse.MemberInformationResponse> getMemberInformation(
@PathVariable Long memberId
) {
ManageMemberResponse.MemberInformationResponse memberInformation
= manageMemberApplication.getMember(memberId);

return ResponseEntity.ok(memberInformation);
}

@PatchMapping(value = "/profile-image/{memberId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<ManageMemberResponse.ObjectUrlResponse> updateProfileImage(
@PathVariable Long memberId,
@RequestPart(value = "image") MultipartFile image
) {
ManageMemberResponse.ObjectUrlResponse objectUrlResponse
= manageMemberApplication.updateProfileImage(memberId, image);
return ResponseEntity.ok(objectUrlResponse);
}

@PatchMapping("/fcm-token/{memberId}")
public ResponseEntity<Void> updateFcmToken(
@PathVariable Long memberId,
@RequestBody ManageMemberRequest.UpdateFcmTokenDto updateFcmTokenDto
) {
manageMemberApplication.updateFcmToken(memberId, updateFcmTokenDto);
return ResponseEntity.ok().build();
}

@PatchMapping("/nickname/{memberId}")
public ResponseEntity<Void> updateNickname(
@PathVariable Long memberId,
@RequestBody ManageMemberRequest.UpdateNicknameDto updateNicknameDto) {
manageMemberApplication.updateNickname(memberId, updateNicknameDto);
return ResponseEntity.ok().build();
}

@DeleteMapping("/{memberId}")
public ResponseEntity<Void> deleteMember(
@PathVariable Long memberId,
HttpServletRequest httpServletRequest
) {
manageMemberApplication.deleteMember(memberId, httpServletRequest);
return ResponseEntity.ok().build();
}
}


Loading

0 comments on commit 802cc92

Please sign in to comment.