diff --git a/src/main/java/poomasi/domain/auth/config/SecurityBeanGenerator.java b/src/main/java/poomasi/domain/auth/config/SecurityBeanGenerator.java index 2a067e4d..2aa3d5d6 100644 --- a/src/main/java/poomasi/domain/auth/config/SecurityBeanGenerator.java +++ b/src/main/java/poomasi/domain/auth/config/SecurityBeanGenerator.java @@ -21,9 +21,6 @@ @Configuration public class SecurityBeanGenerator { - private final TokenStorageService tokenStorageService; - private final MemberService memberService; - private final TokenBlacklistService tokenBlacklistService; @Bean @Description("AuthenticationProvider를 위한 Spring bean") @@ -37,11 +34,5 @@ MvcRequestMatcher.Builder mvc(HandlerMappingIntrospector introspector) { return new MvcRequestMatcher.Builder(introspector); } - @Bean - JwtUtil jwtUtil(){ - return new JwtUtil(tokenBlacklistService, - tokenStorageService, - memberService); - } } diff --git a/src/main/java/poomasi/domain/auth/security/userdetail/OAuth2UserDetailServiceImpl.java b/src/main/java/poomasi/domain/auth/security/userdetail/OAuth2UserDetailServiceImpl.java index 34e8a261..a595b326 100644 --- a/src/main/java/poomasi/domain/auth/security/userdetail/OAuth2UserDetailServiceImpl.java +++ b/src/main/java/poomasi/domain/auth/security/userdetail/OAuth2UserDetailServiceImpl.java @@ -52,7 +52,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic //일단 없으면 가입시키는 쪽으로 구현ㄴ - Member member = memberRepository.findByEmail(email).orElse(null); + Member member = memberRepository.findByEmailAndDeletedAtIsNull(email).orElse(null); if(member == null) { member = Member.builder() .email(email) diff --git a/src/main/java/poomasi/domain/auth/security/userdetail/UserDetailsServiceImpl.java b/src/main/java/poomasi/domain/auth/security/userdetail/UserDetailsServiceImpl.java index e14131fa..86e2ff7b 100644 --- a/src/main/java/poomasi/domain/auth/security/userdetail/UserDetailsServiceImpl.java +++ b/src/main/java/poomasi/domain/auth/security/userdetail/UserDetailsServiceImpl.java @@ -19,7 +19,7 @@ public UserDetailsServiceImpl(MemberRepository memberRepository) { @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { - Member member = memberRepository.findByEmail(email) + Member member = memberRepository.findByEmailAndDeletedAtIsNull(email) .orElseThrow(() -> new BusinessException(BusinessError.MEMBER_NOT_FOUND)); return new UserDetailsImpl(member); } diff --git a/src/main/java/poomasi/domain/auth/signup/service/SignupService.java b/src/main/java/poomasi/domain/auth/signup/service/SignupService.java deleted file mode 100644 index 7099ec8b..00000000 --- a/src/main/java/poomasi/domain/auth/signup/service/SignupService.java +++ /dev/null @@ -1,47 +0,0 @@ -package poomasi.domain.auth.signup.service; - -import jdk.jfr.Description; -import lombok.RequiredArgsConstructor; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import poomasi.domain.member.dto.request.SignupRequest; -import poomasi.domain.member.dto.response.SignUpResponse; -import poomasi.domain.member.entity.LoginType; -import poomasi.domain.member.repository.MemberRepository; -import poomasi.domain.member.entity.Member; -import poomasi.global.error.BusinessException; - -import static poomasi.domain.member.entity.Role.ROLE_CUSTOMER; -import static poomasi.domain.member.entity.Role.ROLE_FARMER; -import static poomasi.global.error.BusinessError.*; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class SignupService { - - private final MemberRepository memberRepository; - private final PasswordEncoder passwordEncoder; - - @Description("카카오톡으로 먼저 회원가입이 되어 있는 경우, 계정 연동을 진행합니다. ") - @Transactional - public SignUpResponse signUp(SignupRequest signupRequest) { - String email = signupRequest.email(); - String password = signupRequest.password(); - - memberRepository.findByEmail(email) - .ifPresent(member -> { throw new BusinessException(DUPLICATE_MEMBER_EMAIL); }); - - Member newMember = Member.builder() - .email(email) - .password(passwordEncoder.encode(password)) - .loginType(LoginType.LOCAL) - .role(ROLE_FARMER) - .build(); - memberRepository.save(newMember); - return new SignUpResponse(email, "회원 가입 성공"); - } -} - diff --git a/src/main/java/poomasi/domain/auth/token/refreshtoken/service/RefreshTokenService.java b/src/main/java/poomasi/domain/auth/token/refreshtoken/service/RefreshTokenService.java index c7111a58..5673353a 100644 --- a/src/main/java/poomasi/domain/auth/token/refreshtoken/service/RefreshTokenService.java +++ b/src/main/java/poomasi/domain/auth/token/refreshtoken/service/RefreshTokenService.java @@ -1,7 +1,6 @@ package poomasi.domain.auth.token.refreshtoken.service; import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; diff --git a/src/main/java/poomasi/domain/auth/token/reissue/controller/ReissueTokenController.java b/src/main/java/poomasi/domain/auth/token/reissue/controller/ReissueTokenController.java index 43aeb0c8..24f80ba0 100644 --- a/src/main/java/poomasi/domain/auth/token/reissue/controller/ReissueTokenController.java +++ b/src/main/java/poomasi/domain/auth/token/reissue/controller/ReissueTokenController.java @@ -1,30 +1,29 @@ package poomasi.domain.auth.token.reissue.controller; - -import org.springframework.beans.factory.annotation.Autowired; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseEntity; -import org.springframework.security.access.annotation.Secured; -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.RequestHeader; import org.springframework.web.bind.annotation.RestController; -import poomasi.domain.auth.security.userdetail.UserDetailsImpl; import poomasi.domain.auth.token.reissue.dto.ReissueRequest; import poomasi.domain.auth.token.reissue.dto.ReissueResponse; import poomasi.domain.auth.token.reissue.service.ReissueTokenService; -import poomasi.domain.member.entity.Member; @RestController +@RequiredArgsConstructor public class ReissueTokenController { - @Autowired - private ReissueTokenService reissueTokenService; + private final ReissueTokenService reissueTokenService; - @Secured({"ROLE_FARMER", "ROLE_CUSTOMER"}) @PostMapping("/api/reissue") - public ResponseEntity reissue(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody ReissueRequest reissueRequest){ - Member member = userDetails.getMember(); - return ResponseEntity.ok(reissueTokenService.reissueToken(member.getId(), reissueRequest)); + public ResponseEntity reissue(@RequestHeader(HttpHeaders.AUTHORIZATION) String authorizationHeader, + @RequestBody ReissueRequest reissueRequest){ + + String accessToken = authorizationHeader.replace("Bearer ", ""); + + return ResponseEntity.ok(reissueTokenService.reissueToken(accessToken, reissueRequest)); } } diff --git a/src/main/java/poomasi/domain/auth/token/reissue/service/ReissueTokenService.java b/src/main/java/poomasi/domain/auth/token/reissue/service/ReissueTokenService.java index 89b379e5..b0b21182 100644 --- a/src/main/java/poomasi/domain/auth/token/reissue/service/ReissueTokenService.java +++ b/src/main/java/poomasi/domain/auth/token/reissue/service/ReissueTokenService.java @@ -18,7 +18,9 @@ public class ReissueTokenService { private final RefreshTokenService refreshTokenService; // 토큰 재발급 - public ReissueResponse reissueToken(Long memberId, ReissueRequest reissueRequest) { + public ReissueResponse reissueToken(String accessToken, ReissueRequest reissueRequest) { + Long memberId = jwtUtil.getIdFromToken(accessToken); + String refreshToken = reissueRequest.refreshToken(); Long requestMemberId = jwtUtil.getIdFromToken(refreshToken); diff --git a/src/main/java/poomasi/domain/image/controller/ImageController.java b/src/main/java/poomasi/domain/image/controller/ImageController.java index d9211481..26000941 100644 --- a/src/main/java/poomasi/domain/image/controller/ImageController.java +++ b/src/main/java/poomasi/domain/image/controller/ImageController.java @@ -22,7 +22,7 @@ public class ImageController { // 이미지 정보 저장 @PostMapping - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity saveImageInfo(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody ImageRequest imageRequest) { Member member = userDetails.getMember(); Image savedImage = imageService.saveImage(member.getId(), imageRequest); @@ -31,7 +31,7 @@ public ResponseEntity saveImageInfo(@AuthenticationPrincipal UserDetailsImpl // 여러 이미지 정보 저장 @PostMapping("/multiple") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity> saveMultipleImages(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody List imageRequests) { Member member = userDetails.getMember(); List savedImages = imageService.saveMultipleImages(member.getId(), imageRequests); @@ -40,7 +40,7 @@ public ResponseEntity> saveMultipleImages(@AuthenticationPrincipal U // 특정 이미지 삭제 @DeleteMapping("/delete/{id}") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity deleteImage(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable Long id) { Member member = userDetails.getMember(); imageService.deleteImage(member.getId(), id); @@ -62,7 +62,7 @@ public ResponseEntity> getImagesByTypeAndReference(@PathVariable Ima // 이미지 정보 수정 @PutMapping("update/{id}") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity updateImageInfo(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable Long id, @RequestBody ImageRequest imageRequest) { @@ -72,7 +72,7 @@ public ResponseEntity updateImageInfo(@AuthenticationPrincipal UserDetailsImp } @PutMapping("/recover/{id}") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity recoverImage(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable Long id) { Member member = userDetails.getMember(); imageService.recoverImage(member.getId(), id); diff --git a/src/main/java/poomasi/domain/image/repository/ImageRepository.java b/src/main/java/poomasi/domain/image/repository/ImageRepository.java index 2b82bad1..3c7162b5 100644 --- a/src/main/java/poomasi/domain/image/repository/ImageRepository.java +++ b/src/main/java/poomasi/domain/image/repository/ImageRepository.java @@ -1,12 +1,14 @@ package poomasi.domain.image.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; import poomasi.domain.image.entity.Image; import poomasi.domain.image.entity.ImageType; import java.util.List; import java.util.Optional; +@Repository public interface ImageRepository extends JpaRepository { long countByTypeAndReferenceIdAndDeletedAtIsNull(ImageType type, Long referenceId); List findByTypeAndReferenceIdAndDeletedAtIsNull(ImageType type, Long referenceId); diff --git a/src/main/java/poomasi/domain/image/service/ImageService.java b/src/main/java/poomasi/domain/image/service/ImageService.java index eede9992..cf72c618 100644 --- a/src/main/java/poomasi/domain/image/service/ImageService.java +++ b/src/main/java/poomasi/domain/image/service/ImageService.java @@ -10,7 +10,7 @@ import poomasi.domain.image.validation.ImageOwnerValidator; import poomasi.domain.image.validation.ImageOwnerValidatorFactory; import poomasi.domain.member._profile.entity.MemberProfile; -import poomasi.domain.member._profile.repository.MemberProfileRepository; +import poomasi.domain.member._profile.service.MemberProfileService; import poomasi.domain.member.entity.Member; import poomasi.domain.member.repository.MemberRepository; import poomasi.global.error.BusinessException; @@ -26,10 +26,14 @@ @RequiredArgsConstructor @Transactional(readOnly = true) public class ImageService { + + private static final int DEFAULT_IMAGE_LIMIT = 5; + private static final int MEMBER_PROFILE_IMAGE_LIMIT = 1; + private final ImageRepository imageRepository; private final ImageOwnerValidatorFactory validatorFactory; private final MemberRepository memberRepository; - private final MemberProfileRepository memberProfileRepository; + private final MemberProfileService memberProfileService; @Transactional @@ -83,8 +87,10 @@ private Image recoverImageOrThrow(Image existingImage, ImageRequest imageRequest } private void validateImageLimit(ImageRequest imageRequest) { - int imageLimit = 5; - if (imageRequest.type() == ImageType.MEMBER_PROFILE) imageLimit = 1; // 멤버 프로필 이미지는 한 장으로 제한 + int imageLimit = DEFAULT_IMAGE_LIMIT; + if (imageRequest.type() == ImageType.MEMBER_PROFILE) { + imageLimit = MEMBER_PROFILE_IMAGE_LIMIT; // 멤버 프로필 이미지는 한 장으로 제한 + } if (imageRepository.countByTypeAndReferenceIdAndDeletedAtIsNull(imageRequest.type(), imageRequest.referenceId()) >= imageLimit) { throw new BusinessException(IMAGE_LIMIT_EXCEED); @@ -92,10 +98,9 @@ private void validateImageLimit(ImageRequest imageRequest) { } private void linkImageToMemberProfile(Long referenceId, Image savedImage) { - MemberProfile memberProfile = memberProfileRepository.findById(referenceId) - .orElseThrow(() -> new BusinessException(MEMBER_PROFILE_NOT_FOUND)); + MemberProfile memberProfile = memberProfileService.getMemberProfileById(referenceId); memberProfile.setProfileImage(savedImage); - memberProfileRepository.save(memberProfile); + memberProfileService.saveMemberProfile(memberProfile); } // 여러 이미지 저장 diff --git a/src/main/java/poomasi/domain/member/_profile/controller/MemberProfileController.java b/src/main/java/poomasi/domain/member/_profile/controller/MemberProfileController.java new file mode 100644 index 00000000..97de1cdf --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/controller/MemberProfileController.java @@ -0,0 +1,14 @@ +package poomasi.domain.member._profile.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import poomasi.domain.member._profile.service.MemberProfileService; + +@RestController +@RequiredArgsConstructor +@RequestMapping("api/member/profile") +public class MemberProfileController { + + private final MemberProfileService memberProfileService; +} diff --git a/src/main/java/poomasi/domain/member/_profile/dto/request/MemberProfileRequest.java b/src/main/java/poomasi/domain/member/_profile/dto/request/MemberProfileRequest.java new file mode 100644 index 00000000..3492e58d --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/dto/request/MemberProfileRequest.java @@ -0,0 +1,5 @@ +package poomasi.domain.member._profile.dto.request; + + +public record MemberProfileRequest() { +} diff --git a/src/main/java/poomasi/domain/member/_profile/dto/response/CommonProfileResponse.java b/src/main/java/poomasi/domain/member/_profile/dto/response/CommonProfileResponse.java new file mode 100644 index 00000000..cb665655 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/dto/response/CommonProfileResponse.java @@ -0,0 +1,25 @@ +package poomasi.domain.member._profile.dto.response; + +import lombok.AllArgsConstructor; +import poomasi.domain.image.entity.Image; +import poomasi.domain.member._profile.entity.MemberProfile; + +import java.time.LocalDateTime; + +@AllArgsConstructor +public class CommonProfileResponse implements MemberProfileResponse { + String phoneNumber; + boolean isBanned; + LocalDateTime createdAt; + Image profileImage; + + public static CommonProfileResponse fromEntity(MemberProfile profile) { + return new CommonProfileResponse( + profile.getPhoneNumber(), + profile.isBanned(), + profile.getCreatedAt(), + profile.getProfileImage() + ); + } + +} diff --git a/src/main/java/poomasi/domain/member/_profile/dto/response/CustomerProfileResponse.java b/src/main/java/poomasi/domain/member/_profile/dto/response/CustomerProfileResponse.java new file mode 100644 index 00000000..53501e03 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/dto/response/CustomerProfileResponse.java @@ -0,0 +1,28 @@ +package poomasi.domain.member._profile.dto.response; + +import lombok.AllArgsConstructor; +import poomasi.domain.image.entity.Image; +import poomasi.domain.member._profile.entity.CustomerProfile; + +import java.time.LocalDateTime; + +@AllArgsConstructor +public class CustomerProfileResponse implements MemberProfileResponse{ + String phoneNumber; + String address; + String addressDetail; + boolean isBanned; + LocalDateTime createdAt; + Image profileImage; + + public static CustomerProfileResponse fromEntity(CustomerProfile profile) { + return new CustomerProfileResponse( + profile.getPhoneNumber(), + profile.getAddress(), + profile.getAddressDetail(), + profile.isBanned(), + profile.getCreatedAt(), + profile.getProfileImage() + ); + } +} \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/_profile/dto/response/FarmerProfileResponse.java b/src/main/java/poomasi/domain/member/_profile/dto/response/FarmerProfileResponse.java new file mode 100644 index 00000000..53fed2f5 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/dto/response/FarmerProfileResponse.java @@ -0,0 +1,39 @@ +package poomasi.domain.member._profile.dto.response; + +import lombok.AllArgsConstructor; +import poomasi.domain.image.entity.Image; +import poomasi.domain.member._profile.entity.FarmerProfile; + +import java.time.LocalDateTime; +import java.util.List; + +@AllArgsConstructor +public class FarmerProfileResponse implements MemberProfileResponse { + String phoneNumber; + boolean isBanned; + LocalDateTime createdAt; + Image profileImage; + String storeName; + String farmName; + List businessRegistrationNumbers; + String storeAddress; + String storeAddressDetail; + String farmAddress; + String farmAddressDetail; + + public static FarmerProfileResponse fromEntity(FarmerProfile profile) { + return new FarmerProfileResponse( + profile.getPhoneNumber(), + profile.isBanned(), + profile.getCreatedAt(), + profile.getProfileImage(), + profile.getStoreName(), + profile.getFarmName(), + profile.getBusinessRegistrationNumbers(), + profile.getStoreAddress(), + profile.getStoreAddressDetail(), + profile.getFarmAddress(), + profile.getFarmAddressDetail() + ); + } +} \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/_profile/dto/response/MemberProfileResponse.java b/src/main/java/poomasi/domain/member/_profile/dto/response/MemberProfileResponse.java new file mode 100644 index 00000000..b191dda0 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/dto/response/MemberProfileResponse.java @@ -0,0 +1,18 @@ +package poomasi.domain.member._profile.dto.response; + +import poomasi.domain.member._profile.entity.CustomerProfile; +import poomasi.domain.member._profile.entity.FarmerProfile; +import poomasi.domain.member._profile.entity.MemberProfile; + +public interface MemberProfileResponse { + + static MemberProfileResponse fromEntity(MemberProfile profile) { + if (profile instanceof FarmerProfile farmerProfile) { + return FarmerProfileResponse.fromEntity(farmerProfile); + } else if (profile instanceof CustomerProfile customerProfile) { + return CustomerProfileResponse.fromEntity(customerProfile); + } else { + return CommonProfileResponse.fromEntity(profile); + } + } +} \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/_profile/entity/CustomerProfile.java b/src/main/java/poomasi/domain/member/_profile/entity/CustomerProfile.java new file mode 100644 index 00000000..ea7b83ad --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/entity/CustomerProfile.java @@ -0,0 +1,23 @@ +package poomasi.domain.member._profile.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.DiscriminatorValue; +import jakarta.persistence.Entity; +import lombok.Getter; + +@Entity +@Getter +@DiscriminatorValue("CUSTOMER") +public class CustomerProfile extends MemberProfile{ + @Column(nullable = true, length = 255) + private String address; + + @Column(nullable = true, length = 255) + private String addressDetail; + + @Column(nullable=true, length=255) + private Long coordinateX; + + @Column(nullable=true, length=255) + private Long coordinateY; +} diff --git a/src/main/java/poomasi/domain/member/_profile/entity/FarmerProfile.java b/src/main/java/poomasi/domain/member/_profile/entity/FarmerProfile.java new file mode 100644 index 00000000..06b946c7 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/entity/FarmerProfile.java @@ -0,0 +1,47 @@ +package poomasi.domain.member._profile.entity; + +import jakarta.persistence.*; +import lombok.Getter; + +import java.util.List; + +@Entity +@Getter +@DiscriminatorValue("FARMER") +public class FarmerProfile extends MemberProfile{ + @Column(nullable = true, length = 100, unique = true) + private String storeName; + + @Column(nullable = true, length = 100) + private String storeAddress; + + @Column(nullable = true, length = 100) + private String storeAddressDetail; + + @Column(nullable=true, length=100) + private Long storeCoordinateX; + + @Column(nullable=true, length=100) + private Long storeCoordinateY; + + @Column(nullable = true, length = 100, unique = true) + private String farmName; + + @Column(nullable = true, length = 100) + private String farmAddress; + + @Column(nullable = true, length = 100) + private String farmAddressDetail; + + @Column(nullable=true, length=100) + private Long farmCoordinateX; + + @Column(nullable=true, length=100) + private Long farmCoordinateY; + + @ElementCollection + @CollectionTable(name = "business_registration_numbers", joinColumns = @JoinColumn(name = "farmer_profile_id")) + @Column(nullable = true, length=255) + private List businessRegistrationNumbers; + +} diff --git a/src/main/java/poomasi/domain/member/_profile/entity/MemberProfile.java b/src/main/java/poomasi/domain/member/_profile/entity/MemberProfile.java index 10359311..af2b5849 100644 --- a/src/main/java/poomasi/domain/member/_profile/entity/MemberProfile.java +++ b/src/main/java/poomasi/domain/member/_profile/entity/MemberProfile.java @@ -12,30 +12,17 @@ @Table(name = "member_profile") @AllArgsConstructor @Builder +@Inheritance(strategy = InheritanceType.JOINED) +@DiscriminatorColumn(name = "profile_type") public class MemberProfile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(nullable = true, length = 50) - private String name; - @Column(nullable = true, length = 20) private String phoneNumber; - @Column(nullable = true, length = 255) - private String address; - - @Column(nullable = true, length = 255) - private String addressDetail; - - @Column(nullable=true, length=255) - private Long coordinateX; - - @Column(nullable=true, length=255) - private Long coordinateY; - @Column(nullable = false) @Builder.Default private boolean isBanned = false; @@ -59,7 +46,5 @@ public void prePersist() { } public MemberProfile() { - this.name = "UNKNOWN"; // name not null 조건 때문에 임시로 넣었습니다. nullable도 true로 넣었는데 안 되네요 } - } diff --git a/src/main/java/poomasi/domain/member/_profile/repository/MemberProfileRepository.java b/src/main/java/poomasi/domain/member/_profile/repository/MemberProfileRepository.java index ee260f12..f59a2490 100644 --- a/src/main/java/poomasi/domain/member/_profile/repository/MemberProfileRepository.java +++ b/src/main/java/poomasi/domain/member/_profile/repository/MemberProfileRepository.java @@ -1,7 +1,19 @@ package poomasi.domain.member._profile.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; +import poomasi.domain.member._profile.entity.FarmerProfile; import poomasi.domain.member._profile.entity.MemberProfile; +import java.util.Optional; + +@Repository public interface MemberProfileRepository extends JpaRepository { + + // FarmerProfile 타입만 조회 +// @Query("SELECT p FROM FarmerProfile p WHERE p.farmName = :farmName") +// Optional findFarmerByFarmName(@Param("farmName") String farmName); + } \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/_profile/service/MemberProfileService.java b/src/main/java/poomasi/domain/member/_profile/service/MemberProfileService.java new file mode 100644 index 00000000..3f88b3c4 --- /dev/null +++ b/src/main/java/poomasi/domain/member/_profile/service/MemberProfileService.java @@ -0,0 +1,28 @@ +package poomasi.domain.member._profile.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import poomasi.domain.member._profile.entity.MemberProfile; +import poomasi.domain.member._profile.repository.MemberProfileRepository; +import poomasi.global.error.BusinessException; + +import static poomasi.global.error.BusinessError.MEMBER_PROFILE_NOT_FOUND; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MemberProfileService { + + private final MemberProfileRepository memberProfileRepository; + + public MemberProfile getMemberProfileById(Long id){ + return memberProfileRepository.findById(id) + .orElseThrow(() -> new BusinessException(MEMBER_PROFILE_NOT_FOUND)); + } + + @Transactional + public MemberProfile saveMemberProfile(MemberProfile memberProfile){ + return memberProfileRepository.save(memberProfile); + } +} diff --git a/src/main/java/poomasi/domain/member/controller/MemberController.java b/src/main/java/poomasi/domain/member/controller/MemberController.java index 8f057dba..2ee754f3 100644 --- a/src/main/java/poomasi/domain/member/controller/MemberController.java +++ b/src/main/java/poomasi/domain/member/controller/MemberController.java @@ -30,11 +30,12 @@ public ResponseEntity signUp(@RequestBody SignupRequest signupRe .signUp(signupRequest)); } - @PutMapping("/toFarmer/{memberId}") - @Secured("ROLE_ADMIN") - public ResponseEntity convertToFarmer(@PathVariable Long memberId, + @PutMapping("/toFarmer") + @Secured("ROLE_CUSTOMER") + public ResponseEntity convertToFarmer(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody FarmerQualificationRequest request) { - memberService.convertToFarmer(memberId, request.hasFarmerQualification()); + Member member = userDetails.getMember(); + memberService.convertToFarmer(member, request.hasFarmerQualification()); return ResponseEntity.noContent().build(); } @@ -52,15 +53,15 @@ public ResponseEntity getMemberById(@PathVariable Long memberId) return ResponseEntity.ok(memberResponse); } - @GetMapping + @GetMapping("/summary") @Secured("ROLE_ADMIN") - public ResponseEntity> getMembers(@PageableDefault(size = 10) Pageable pageable) { - Page memberResponses = memberService.getAllMembers(pageable); - return ResponseEntity.ok(memberResponses); + public ResponseEntity> getMembersSummary(@PageableDefault(size = 10) Pageable pageable) { + Page memberSummaryResponses = memberService.getAllMembersSummary(pageable); + return ResponseEntity.ok(memberSummaryResponses); } @GetMapping("/self") - @Secured({"ROLE_MEMBER", "ROLE_FARMER"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity getSelfMember(@AuthenticationPrincipal UserDetailsImpl userDetails) { Member member = userDetails.getMember(); MemberResponse memberResponse = memberService.getMemberById(member.getId()); @@ -68,7 +69,7 @@ public ResponseEntity getSelfMember(@AuthenticationPrincipal Use } @GetMapping("/summary/{memberId}") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity getMemberSummaryById(@PathVariable Long memberId) { MemberSummaryResponse memberSummaryResponse = memberService.getMemberSummary(memberId); return ResponseEntity.ok(memberSummaryResponse); diff --git a/src/main/java/poomasi/domain/member/dto/request/SignupRequest.java b/src/main/java/poomasi/domain/member/dto/request/SignupRequest.java index 447bdf9b..85bbe7ab 100644 --- a/src/main/java/poomasi/domain/member/dto/request/SignupRequest.java +++ b/src/main/java/poomasi/domain/member/dto/request/SignupRequest.java @@ -1,4 +1,4 @@ package poomasi.domain.member.dto.request; -public record SignupRequest(String email, String password) { +public record SignupRequest(String name, String email, String password) { } diff --git a/src/main/java/poomasi/domain/member/dto/response/MemberProfileResponse.java b/src/main/java/poomasi/domain/member/dto/response/MemberProfileResponse.java deleted file mode 100644 index d7ad6655..00000000 --- a/src/main/java/poomasi/domain/member/dto/response/MemberProfileResponse.java +++ /dev/null @@ -1,32 +0,0 @@ -package poomasi.domain.member.dto.response; - -import poomasi.domain.image.entity.Image; -import poomasi.domain.member._profile.entity.MemberProfile; - -import java.time.LocalDateTime; - -public record MemberProfileResponse( - String name, - String phoneNumber, - String address, - String addressDetail, - Long coordinateX, - Long coordinateY, - boolean isBanned, - LocalDateTime createdAt, - Image profileImage -) { - public static MemberProfileResponse fromEntity(MemberProfile profile) { - return new MemberProfileResponse( - profile.getName(), - profile.getPhoneNumber(), - profile.getAddress(), - profile.getAddressDetail(), - profile.getCoordinateX(), - profile.getCoordinateY(), - profile.isBanned(), - profile.getCreatedAt(), - profile.getProfileImage() - ); - } -} \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/dto/response/MemberResponse.java b/src/main/java/poomasi/domain/member/dto/response/MemberResponse.java index f19c14c3..98a8c464 100644 --- a/src/main/java/poomasi/domain/member/dto/response/MemberResponse.java +++ b/src/main/java/poomasi/domain/member/dto/response/MemberResponse.java @@ -1,9 +1,11 @@ package poomasi.domain.member.dto.response; +import poomasi.domain.member._profile.dto.response.MemberProfileResponse; import poomasi.domain.member.entity.Member; public record MemberResponse( Long id, + String name, String email, String role, MemberProfileResponse memberProfile @@ -11,6 +13,7 @@ public record MemberResponse( public static MemberResponse fromEntity(Member member) { return new MemberResponse( member.getId(), + member.getName(), member.getEmail(), member.getRole().name(), member.getMemberProfile() != null ? MemberProfileResponse.fromEntity(member.getMemberProfile()) : null diff --git a/src/main/java/poomasi/domain/member/dto/response/MemberSummaryResponse.java b/src/main/java/poomasi/domain/member/dto/response/MemberSummaryResponse.java index 9691eab0..f57c1bfa 100644 --- a/src/main/java/poomasi/domain/member/dto/response/MemberSummaryResponse.java +++ b/src/main/java/poomasi/domain/member/dto/response/MemberSummaryResponse.java @@ -6,7 +6,7 @@ public record MemberSummaryResponse(String name, Image profileImage) { public static MemberSummaryResponse fromEntity(Member member) { return new MemberSummaryResponse( - member.getMemberProfile().getName(), + member.getName(), member.getMemberProfile().getProfileImage() ); } diff --git a/src/main/java/poomasi/domain/member/dto/response/SignUpResponse.java b/src/main/java/poomasi/domain/member/dto/response/SignUpResponse.java index 02280570..bf4a5ecb 100644 --- a/src/main/java/poomasi/domain/member/dto/response/SignUpResponse.java +++ b/src/main/java/poomasi/domain/member/dto/response/SignUpResponse.java @@ -1,4 +1,4 @@ package poomasi.domain.member.dto.response; -public record SignUpResponse(String email, String message) { +public record SignUpResponse(String name, String email, String message) { } diff --git a/src/main/java/poomasi/domain/member/entity/Member.java b/src/main/java/poomasi/domain/member/entity/Member.java index fa2e8759..a18c99c2 100644 --- a/src/main/java/poomasi/domain/member/entity/Member.java +++ b/src/main/java/poomasi/domain/member/entity/Member.java @@ -10,6 +10,7 @@ import poomasi.domain.order.entity.Order; import poomasi.domain.store.entity.Store; import poomasi.domain.member._profile.entity.MemberProfile; +import poomasi.domain.store.entity.Store; import poomasi.domain.wishlist.entity.WishList; import poomasi.global.error.BusinessError; import poomasi.global.error.BusinessException; @@ -26,6 +27,9 @@ public class Member { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = true, length = 50) + private String name; + @Column(unique = true, nullable = true, length = 50) private String email; @@ -65,18 +69,14 @@ public class Member { @OneToOne(mappedBy="owner", cascade = CascadeType.ALL, fetch = FetchType.LAZY) Store store; - public Member(String email, String password, LoginType loginType, Role role) { + public Member(String name, String email, String password, LoginType loginType, Role role) { + this.name = name; this.email = email; this.password = password; this.loginType = loginType; this.role = role; } - public Member(String email, Role role) { - this.email = email; - this.role = role; - } - public void setMemberProfile(MemberProfile memberProfile) { this.memberProfile = memberProfile; if (memberProfile != null) { diff --git a/src/main/java/poomasi/domain/member/repository/MemberRepository.java b/src/main/java/poomasi/domain/member/repository/MemberRepository.java index f9bcb1c3..4e3cea7e 100644 --- a/src/main/java/poomasi/domain/member/repository/MemberRepository.java +++ b/src/main/java/poomasi/domain/member/repository/MemberRepository.java @@ -7,6 +7,6 @@ import java.util.Optional; public interface MemberRepository extends JpaRepository { - Optional findByEmail(String email); + Optional findByEmailAndDeletedAtIsNull(String email); Optional findByIdAndDeletedAtIsNull(Long id); -} +} \ No newline at end of file diff --git a/src/main/java/poomasi/domain/member/service/MemberService.java b/src/main/java/poomasi/domain/member/service/MemberService.java index 9a9d51b2..c386ee3c 100644 --- a/src/main/java/poomasi/domain/member/service/MemberService.java +++ b/src/main/java/poomasi/domain/member/service/MemberService.java @@ -31,19 +31,20 @@ public class MemberService { @Description("카카오톡으로 먼저 회원가입이 되어 있는 경우, 계정 연동을 진행합니다. ") @Transactional public SignUpResponse signUp(SignupRequest signupRequest) { + String name = signupRequest.name(); String email = signupRequest.email(); String password = signupRequest.password(); - memberRepository.findByEmail(email) + memberRepository.findByEmailAndDeletedAtIsNull(email) .ifPresent(member -> { throw new BusinessException(DUPLICATE_MEMBER_EMAIL); }); - Member newMember = new Member(email, + Member newMember = new Member(name, email, passwordEncoder.encode(password), LoginType.LOCAL, ROLE_CUSTOMER); memberRepository.save(newMember); - return new SignUpResponse(email, "회원 가입 성공"); + return new SignUpResponse(name, email, "회원 가입 성공"); } public MemberResponse getMemberById(Long memberId) { @@ -56,15 +57,13 @@ public MemberSummaryResponse getMemberSummary(Long memberId) { return MemberSummaryResponse.fromEntity(member); } - public Page getAllMembers(Pageable pageable) { + public Page getAllMembersSummary(Pageable pageable) { Page members = memberRepository.findAll(pageable); - return members.map(MemberResponse::fromEntity); + return members.map(MemberSummaryResponse::fromEntity); } @Transactional - public void convertToFarmer(Long memberId, Boolean hasFarmerQualification) { - Member member = findMemberById(memberId); - + public void convertToFarmer(Member member, Boolean hasFarmerQualification) { if (member.isFarmer()) { throw new BusinessException(MEMBER_ALREADY_FARMER); } diff --git a/src/main/java/poomasi/domain/review/dto/ReviewResponse.java b/src/main/java/poomasi/domain/review/dto/ReviewResponse.java index 52524f66..1b6ac560 100644 --- a/src/main/java/poomasi/domain/review/dto/ReviewResponse.java +++ b/src/main/java/poomasi/domain/review/dto/ReviewResponse.java @@ -15,7 +15,7 @@ public static ReviewResponse fromEntity(Review review) { return new ReviewResponse( review.getId(), review.getEntityId(), - review.getReviewer().getMemberProfile()==null?"":review.getReviewer().getMemberProfile().getName(), + review.getReviewer().getName(), review.getRating(), review.getContent() ); diff --git a/src/main/java/poomasi/domain/store/dto/StoreResponse.java b/src/main/java/poomasi/domain/store/dto/StoreResponse.java index cb99e0c7..3a821c63 100644 --- a/src/main/java/poomasi/domain/store/dto/StoreResponse.java +++ b/src/main/java/poomasi/domain/store/dto/StoreResponse.java @@ -46,7 +46,7 @@ public static StoreResponse fromEntity(Store store) { .shipingFee(store.getShipingFee()) //TODO 나중에 삼항연산자 삭제 .ownerName( store.getOwner().getMemberProfile() == null ? "" - : store.getOwner().getMemberProfile().getName()) + : store.getOwner().getName()) .products(store.getProducts().stream().map(ProductResponse::fromEntity).toList()) .build(); diff --git a/src/main/java/poomasi/global/config/s3/S3PresignedUrlController.java b/src/main/java/poomasi/global/config/s3/S3PresignedUrlController.java index 12c3ebe5..44f5e52b 100644 --- a/src/main/java/poomasi/global/config/s3/S3PresignedUrlController.java +++ b/src/main/java/poomasi/global/config/s3/S3PresignedUrlController.java @@ -15,14 +15,14 @@ public class S3PresignedUrlController { private final AwsProperties awsProperties; @GetMapping("/presigned-url-get") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity presignedUrlGet(@RequestParam String keyname) { String presignedGetUrl = s3PresignedUrlService.createPresignedGetUrl(awsProperties.getS3().getBucket(), keyname); return ResponseEntity.ok(presignedGetUrl); } @PostMapping("/presigned-url-put") - @Secured({"ROLE_MEMBER", "ROLE_FARMER", "ROLE_ADMIN"}) + @Secured({"ROLE_CUSTOMER", "ROLE_FARMER", "ROLE_ADMIN"}) public ResponseEntity presignedUrlPut(@RequestBody PresignedUrlPutRequest request) { String presignedPutUrl = s3PresignedUrlService.createPresignedPutUrl(awsProperties.getS3().getBucket(), request.keyPrefix(), request.metadata()); return ResponseEntity.ok(presignedPutUrl);