From e3517d5ecdad8ef9edc3a7dc03a5855e139e5441 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Wed, 2 Aug 2023 19:24:02 +0900 Subject: [PATCH 01/11] =?UTF-8?q?refactor:=20=EC=9D=BC=EB=B0=98=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MemberController.java | 15 ++------------- .../couphoneserver/service/MemberService.java | 15 --------------- 2 files changed, 2 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/example/couphoneserver/controller/MemberController.java b/src/main/java/com/example/couphoneserver/controller/MemberController.java index c450556..d00cc8e 100644 --- a/src/main/java/com/example/couphoneserver/controller/MemberController.java +++ b/src/main/java/com/example/couphoneserver/controller/MemberController.java @@ -1,15 +1,12 @@ package com.example.couphoneserver.controller; -import com.example.couphoneserver.common.annotation.NoAuth; import com.example.couphoneserver.common.response.BaseResponse; import com.example.couphoneserver.domain.entity.Member; -import com.example.couphoneserver.dto.member.request.AddMemberRequestDto; import com.example.couphoneserver.dto.member.response.MemberInfoResponseDto; import com.example.couphoneserver.dto.member.response.MemberResponseDto; import com.example.couphoneserver.service.MemberService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; @@ -22,18 +19,10 @@ public class MemberController { private final MemberService memberService; - @NoAuth - @PostMapping - @Operation(summary = "이메일으로 회원 가입", description = - "Request Body 에 이메일, 비밀번호를 담아서 보내면 비밀번호는 DB 에 암호화되어 관리합니다.") - public BaseResponse signup(@Valid @RequestBody AddMemberRequestDto request) { - return new BaseResponse<>(memberService.save(request)); - } - @PatchMapping("/{member-id}") @Operation(summary = "회원 탈퇴", description = "회원의 상태를 TERMINATED 으로 변경합니다. path variable 로 멤버 id 담아서 보내주세요!") - public BaseResponse delete(@PathVariable("member-id") Long memberId){ + public BaseResponse delete(@PathVariable("member-id") Long memberId) { Member member = memberService.findOneById(memberId); return new BaseResponse<>(memberService.delete(member)); } @@ -41,7 +30,7 @@ public BaseResponse delete(@PathVariable("member-id") Long me @GetMapping("/{member-id}") @Operation(summary = "회원 정보 조회", description = "회원 정보를 조회합니다. path variable 로 멤버 id 담아서 보내주세요!") - public BaseResponse show(@PathVariable("member-id") Long memberId){ + public BaseResponse show(@PathVariable("member-id") Long memberId) { Member member = memberService.findOneById(memberId); return new BaseResponse<>(memberService.getMemberInfo(member)); } diff --git a/src/main/java/com/example/couphoneserver/service/MemberService.java b/src/main/java/com/example/couphoneserver/service/MemberService.java index 89a4add..8e0b032 100644 --- a/src/main/java/com/example/couphoneserver/service/MemberService.java +++ b/src/main/java/com/example/couphoneserver/service/MemberService.java @@ -4,7 +4,6 @@ import com.example.couphoneserver.domain.MemberGrade; import com.example.couphoneserver.domain.MemberStatus; import com.example.couphoneserver.domain.entity.Member; -import com.example.couphoneserver.dto.member.request.AddMemberRequestDto; import com.example.couphoneserver.dto.member.request.LoginRequestDto; import com.example.couphoneserver.dto.member.response.LoginResponseDto; import com.example.couphoneserver.dto.member.response.MemberInfoResponseDto; @@ -43,20 +42,6 @@ public class MemberService { private final AuthenticationManagerBuilder authenticationManagerBuilder; private final RefreshTokenService refreshTokenService; - /** - * 이메일로 회원 가입 - */ - @Transactional - public MemberResponseDto save(AddMemberRequestDto dto) throws UsernameNotFoundException { - validateDuplicateMemberByEmail(dto.getEmail()); - validateDuplicateMemberByName(dto.getName()); - Member savedMember = memberRepository.save( - new Member(dto.getName(), dto.getEmail(), bCryptPasswordEncoder.encode(dto.getPassword()), - MemberStatus.ACTIVE, MemberGrade.ROLE_MEMBER) - ); - return new MemberResponseDto(savedMember); - } - @Transactional public void saveByEmailAndName(LoginRequestDto dto) throws UsernameNotFoundException { validateDuplicateMemberByEmail(dto.getEmail()); From 8b147b5d56737575d591d3d22e2a0294245cc964 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Wed, 2 Aug 2023 19:29:42 +0900 Subject: [PATCH 02/11] =?UTF-8?q?refactor:=20=EC=9D=BC=EB=B0=98=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EA=B0=80=EC=9E=85=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/request/AddMemberRequestDto.java | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 src/main/java/com/example/couphoneserver/dto/member/request/AddMemberRequestDto.java diff --git a/src/main/java/com/example/couphoneserver/dto/member/request/AddMemberRequestDto.java b/src/main/java/com/example/couphoneserver/dto/member/request/AddMemberRequestDto.java deleted file mode 100644 index 8c104c5..0000000 --- a/src/main/java/com/example/couphoneserver/dto/member/request/AddMemberRequestDto.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.example.couphoneserver.dto.member.request; - -import com.example.couphoneserver.domain.entity.Member; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import lombok.*; - -@NoArgsConstructor(access = AccessLevel.PROTECTED) -@AllArgsConstructor -@Getter -@ToString -public class AddMemberRequestDto { - @NotNull - @Size(min=3, max=100) - @Schema(example = "김이름") - private String name; - @NotNull - @Email - @Size(min=3, max=100) - @Schema(example = "aaa@naver.com", description = "반드시 이메일 형식이어야 합니다.") - private String email; - @NotNull - @Size(min=3, max=100) - @Schema(example = "1234!@#$") - private String password; - - public Member toEntity(){ - return Member.builder() - .name(name) - .email(email) - .password(password) - .build(); - } -} \ No newline at end of file From 447a7d80f2ff5b9f5009d04020a10f71c7a10231 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Wed, 2 Aug 2023 19:30:52 +0900 Subject: [PATCH 03/11] =?UTF-8?q?refactor:=20Login=20Dto=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B3=80=EA=B2=BD=20[before]=20dto/member=20[after?= =?UTF-8?q?]=20dto/auth?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AuthController.java | 4 ++-- .../request => auth}/LoginRequestDto.java | 2 +- .../response => auth}/LoginResponseDto.java | 2 +- .../couphoneserver/service/MemberService.java | 16 ++++++++-------- .../domain/service/MemberServiceTest.java | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) rename src/main/java/com/example/couphoneserver/dto/{member/request => auth}/LoginRequestDto.java (90%) rename src/main/java/com/example/couphoneserver/dto/{member/response => auth}/LoginResponseDto.java (94%) diff --git a/src/main/java/com/example/couphoneserver/controller/AuthController.java b/src/main/java/com/example/couphoneserver/controller/AuthController.java index f88fad1..8058253 100644 --- a/src/main/java/com/example/couphoneserver/controller/AuthController.java +++ b/src/main/java/com/example/couphoneserver/controller/AuthController.java @@ -2,8 +2,8 @@ import com.example.couphoneserver.common.annotation.NoAuth; import com.example.couphoneserver.common.response.BaseResponse; -import com.example.couphoneserver.dto.member.request.LoginRequestDto; -import com.example.couphoneserver.dto.member.response.LoginResponseDto; +import com.example.couphoneserver.dto.auth.LoginRequestDto; +import com.example.couphoneserver.dto.auth.LoginResponseDto; import com.example.couphoneserver.service.MemberService; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; diff --git a/src/main/java/com/example/couphoneserver/dto/member/request/LoginRequestDto.java b/src/main/java/com/example/couphoneserver/dto/auth/LoginRequestDto.java similarity index 90% rename from src/main/java/com/example/couphoneserver/dto/member/request/LoginRequestDto.java rename to src/main/java/com/example/couphoneserver/dto/auth/LoginRequestDto.java index 575e294..017d546 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/request/LoginRequestDto.java +++ b/src/main/java/com/example/couphoneserver/dto/auth/LoginRequestDto.java @@ -1,4 +1,4 @@ -package com.example.couphoneserver.dto.member.request; +package com.example.couphoneserver.dto.auth; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.Email; diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/LoginResponseDto.java b/src/main/java/com/example/couphoneserver/dto/auth/LoginResponseDto.java similarity index 94% rename from src/main/java/com/example/couphoneserver/dto/member/response/LoginResponseDto.java rename to src/main/java/com/example/couphoneserver/dto/auth/LoginResponseDto.java index 6a6e363..8a71959 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/LoginResponseDto.java +++ b/src/main/java/com/example/couphoneserver/dto/auth/LoginResponseDto.java @@ -1,4 +1,4 @@ -package com.example.couphoneserver.dto.member.response; +package com.example.couphoneserver.dto.auth; import com.example.couphoneserver.domain.MemberGrade; import io.swagger.v3.oas.annotations.media.Schema; diff --git a/src/main/java/com/example/couphoneserver/service/MemberService.java b/src/main/java/com/example/couphoneserver/service/MemberService.java index 8e0b032..0fad623 100644 --- a/src/main/java/com/example/couphoneserver/service/MemberService.java +++ b/src/main/java/com/example/couphoneserver/service/MemberService.java @@ -4,10 +4,10 @@ import com.example.couphoneserver.domain.MemberGrade; import com.example.couphoneserver.domain.MemberStatus; import com.example.couphoneserver.domain.entity.Member; -import com.example.couphoneserver.dto.member.request.LoginRequestDto; -import com.example.couphoneserver.dto.member.response.LoginResponseDto; -import com.example.couphoneserver.dto.member.response.MemberInfoResponseDto; -import com.example.couphoneserver.dto.member.response.MemberResponseDto; +import com.example.couphoneserver.dto.auth.LoginRequestDto; +import com.example.couphoneserver.dto.auth.LoginResponseDto; +import com.example.couphoneserver.dto.member.response.GetMemberResponse; +import com.example.couphoneserver.dto.member.response.PatchMemberResponse; import com.example.couphoneserver.repository.MemberRepository; import com.example.couphoneserver.utils.jwt.JwtTokenProvider; import lombok.RequiredArgsConstructor; @@ -81,9 +81,9 @@ public Long join(Member member) { * 회원 탈퇴 처리 */ @Transactional - public MemberResponseDto delete(Member member) { + public PatchMemberResponse delete(Member member) { member.setTerminated(); - return new MemberResponseDto(member); + return new PatchMemberResponse(member); } @Transactional @@ -116,8 +116,8 @@ public Member findOneByEmail(String email) { /** * 단일 회원 정보 조회 */ - public MemberInfoResponseDto getMemberInfo(Member member) { - return new MemberInfoResponseDto(member); + public GetMemberResponse getMemberInfo(Member member) { + return new GetMemberResponse(member); } /** diff --git a/src/test/java/com/example/couphoneserver/domain/service/MemberServiceTest.java b/src/test/java/com/example/couphoneserver/domain/service/MemberServiceTest.java index bd65ae2..9187f6f 100644 --- a/src/test/java/com/example/couphoneserver/domain/service/MemberServiceTest.java +++ b/src/test/java/com/example/couphoneserver/domain/service/MemberServiceTest.java @@ -3,8 +3,8 @@ import com.example.couphoneserver.common.exception.MemberException; import com.example.couphoneserver.domain.MemberStatus; import com.example.couphoneserver.domain.entity.Member; -import com.example.couphoneserver.dto.member.request.LoginRequestDto; -import com.example.couphoneserver.dto.member.response.LoginResponseDto; +import com.example.couphoneserver.dto.auth.LoginRequestDto; +import com.example.couphoneserver.dto.auth.LoginResponseDto; import com.example.couphoneserver.repository.BrandRepository; import com.example.couphoneserver.repository.MemberRepository; import com.example.couphoneserver.repository.StoreRepository; From 506a2093981ca12d4a06ec4f9c6c00607ff93819 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Wed, 2 Aug 2023 19:31:36 +0900 Subject: [PATCH 04/11] =?UTF-8?q?refactor:=20Member=20Dto=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD=20-=20Http=20=EB=A9=94=EC=86=8C?= =?UTF-8?q?=EB=93=9C=20+=20=EB=8F=84=EB=A9=94=EC=9D=B8=20+=20req/resp=20?= =?UTF-8?q?=ED=98=95=EC=8B=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../couphoneserver/controller/MemberController.java | 8 ++++---- ...{MemberInfoResponseDto.java => GetMemberResponse.java} | 4 ++-- .../{MemberResponseDto.java => PatchMemberResponse.java} | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/main/java/com/example/couphoneserver/dto/member/response/{MemberInfoResponseDto.java => GetMemberResponse.java} (92%) rename src/main/java/com/example/couphoneserver/dto/member/response/{MemberResponseDto.java => PatchMemberResponse.java} (83%) diff --git a/src/main/java/com/example/couphoneserver/controller/MemberController.java b/src/main/java/com/example/couphoneserver/controller/MemberController.java index d00cc8e..6803daf 100644 --- a/src/main/java/com/example/couphoneserver/controller/MemberController.java +++ b/src/main/java/com/example/couphoneserver/controller/MemberController.java @@ -2,8 +2,8 @@ import com.example.couphoneserver.common.response.BaseResponse; import com.example.couphoneserver.domain.entity.Member; -import com.example.couphoneserver.dto.member.response.MemberInfoResponseDto; -import com.example.couphoneserver.dto.member.response.MemberResponseDto; +import com.example.couphoneserver.dto.member.response.GetMemberResponse; +import com.example.couphoneserver.dto.member.response.PatchMemberResponse; import com.example.couphoneserver.service.MemberService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; @@ -22,7 +22,7 @@ public class MemberController { @PatchMapping("/{member-id}") @Operation(summary = "회원 탈퇴", description = "회원의 상태를 TERMINATED 으로 변경합니다. path variable 로 멤버 id 담아서 보내주세요!") - public BaseResponse delete(@PathVariable("member-id") Long memberId) { + public BaseResponse delete(@PathVariable("member-id") Long memberId) { Member member = memberService.findOneById(memberId); return new BaseResponse<>(memberService.delete(member)); } @@ -30,7 +30,7 @@ public BaseResponse delete(@PathVariable("member-id") Long me @GetMapping("/{member-id}") @Operation(summary = "회원 정보 조회", description = "회원 정보를 조회합니다. path variable 로 멤버 id 담아서 보내주세요!") - public BaseResponse show(@PathVariable("member-id") Long memberId) { + public BaseResponse show(@PathVariable("member-id") Long memberId) { Member member = memberService.findOneById(memberId); return new BaseResponse<>(memberService.getMemberInfo(member)); } diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/MemberInfoResponseDto.java b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberResponse.java similarity index 92% rename from src/main/java/com/example/couphoneserver/dto/member/response/MemberInfoResponseDto.java rename to src/main/java/com/example/couphoneserver/dto/member/response/GetMemberResponse.java index ae5b755..40cea59 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/MemberInfoResponseDto.java +++ b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberResponse.java @@ -10,7 +10,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class MemberInfoResponseDto { +public class GetMemberResponse { @Schema(example = "1", description = "회원 아이디") private Long id; @Schema(example = "김이름", description = "회원 이름") @@ -22,7 +22,7 @@ public class MemberInfoResponseDto { @Schema(example = "ACTIVE", description = "회원 상태") private MemberStatus memberStatus; - public MemberInfoResponseDto(Member member) { + public GetMemberResponse(Member member) { id = member.getId(); name = member.getName(); email = member.getEmail(); diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/MemberResponseDto.java b/src/main/java/com/example/couphoneserver/dto/member/response/PatchMemberResponse.java similarity index 83% rename from src/main/java/com/example/couphoneserver/dto/member/response/MemberResponseDto.java rename to src/main/java/com/example/couphoneserver/dto/member/response/PatchMemberResponse.java index f8e5ea7..4fb73c8 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/MemberResponseDto.java +++ b/src/main/java/com/example/couphoneserver/dto/member/response/PatchMemberResponse.java @@ -9,10 +9,10 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class MemberResponseDto { +public class PatchMemberResponse { @Schema(example = "1", description = "회원 아이디") private Long id; - public MemberResponseDto(Member member) { + public PatchMemberResponse(Member member) { id = member.getId(); } } From 02a2500828393447d5def499e2c025a4e61da7e7 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 16:09:23 +0900 Subject: [PATCH 05/11] =?UTF-8?q?feat:=20CouponItemRepository=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=B6=94=EA=B0=80=20-=20findByMemberIdOrd?= =?UTF-8?q?erByStampCountAndCreatedDate=20=EB=8A=94=20=ED=8A=B9=EC=A0=95?= =?UTF-8?q?=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EA=B0=80=EC=A7=80=EA=B3=A0=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EC=BF=A0=ED=8F=B0=EC=9D=84=201.=20?= =?UTF-8?q?=EB=8F=84=EC=9E=A5=20=EA=B0=9C=EC=88=98=20=EB=A7=8E=EC=9D=80=20?= =?UTF-8?q?=EC=88=9C,=202.=20=EC=83=9D=EC=84=B1=EC=8B=9C=EA=B0=84=EC=9D=B4?= =?UTF-8?q?=20=EB=B9=A0=EB=A5=B8=20=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C.=20-=20findByMemberIdOrderByCreatedDateAndStampCount?= =?UTF-8?q?=20=EB=8A=94=20=ED=8A=B9=EC=A0=95=20=ED=9A=8C=EC=9B=90=EC=9D=B4?= =?UTF-8?q?=20=EA=B0=80=EC=A7=80=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EC=BF=A0?= =?UTF-8?q?=ED=8F=B0=EC=9D=84=201.=20=EC=83=9D=EC=84=B1=EC=8B=9C=EA=B0=84?= =?UTF-8?q?=EC=9D=B4=20=EB=B9=A0=EB=A5=B8=20=EC=88=9C,=202.=20=EB=8F=84?= =?UTF-8?q?=EC=9E=A5=20=EA=B0=9C=EC=88=98=EA=B0=80=20=EB=A7=8E=EC=9D=80=20?= =?UTF-8?q?=EC=88=9C=EC=9C=BC=EB=A1=9C=20=EC=A1=B0=ED=9A=8C.=20-=20findByM?= =?UTF-8?q?emberIdOrderByBrandName=20=EB=8A=94=20=ED=8A=B9=EC=A0=95=20?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EA=B0=80=EC=A7=80=EA=B3=A0=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EC=BF=A0=ED=8F=B0=EC=9D=84=20=EB=B8=8C?= =?UTF-8?q?=EB=9E=9C=EB=93=9C=20=EC=9D=B4=EB=A6=84=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CouponItemRepository.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java b/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java index 6f3faf5..85c0574 100644 --- a/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java +++ b/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java @@ -3,12 +3,29 @@ import com.example.couphoneserver.domain.CouponItemStatus; import com.example.couphoneserver.domain.entity.CouponItem; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import java.util.List; import java.util.Optional; public interface CouponItemRepository extends JpaRepository { CouponItem findByMemberIdAndBrandIdAndStatus(Long mid, Long bid, CouponItemStatus status); + List findAllByMemberIdAndBrandId(Long mid, Long bid); + Optional findById(Long couponId); + + // [Note] 만료일이 아니라 생성일로 정렬한 이유는, 만료일은 생성일+6M 이기 때문에 똑같다고 생각했기 떄문입니다. + // 특정 회원이 가지고 있는 쿠폰을 1. 도장 개수 많은 순, 2. 생성시간이 빠른 순으로 조회. + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.stampCount DESC, c.createdDate ASC") + List findByMemberIdOrderByStampCountAndCreatedDate(@Param("memberId") Long memberId); + + // 특정 회원이 가지고 있는 쿠폰을 1. 생성시간이 빠른 순, 2. 도장 개수가 많은 순으로 조회. + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.createdDate, c.stampCount DESC") + List findByMemberIdOrderByCreatedDateAndStampCount(@Param("memberId") Long memberId); + + // 특정 회원이 가지고 있는 쿠폰을 브랜드 이름으로 조회 + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.brand.name") + List findByMemberIdOrderByBrandName(@Param("memberId") Long memberId); } From 0adc20f3a8171a363cf0f6a9770db519cd053b74 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 16:10:47 +0900 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20MemberDto=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?-=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20=EC=86=8C=EC=9C=A0=ED=95=9C?= =?UTF-8?q?=20=EC=BF=A0=ED=8F=B0=EC=9D=98=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EC=A1=B0=ED=9A=8C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/member/response/BrandDto.java | 40 +++++++++++++++++++ .../GetMemberCouponBrandsResponse.java | 34 ++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java create mode 100644 src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java new file mode 100644 index 0000000..33a0ae6 --- /dev/null +++ b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java @@ -0,0 +1,40 @@ +package com.example.couphoneserver.dto.member.response; + +import com.example.couphoneserver.domain.entity.Brand; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +import java.time.LocalDateTime; + +@Getter +public class BrandDto { + @Schema(description = "브랜드 ID", example = "1") + Long id; + + @Schema(description = "브랜드 이름", example = "메가커피") + String name; + + @Schema(description = "보상 방법 (쿠폰 혜택)", example = "아이스 아메리카노 1잔 무료") + String rewardDescription; + + @Schema(description = "브랜드 로고 URL", example = "----") + String brandImageUrl; + + @Schema(description = "스탬프 적립 개수", example = "3") + int stampCount; + + @Schema(description = "생성 시간", example = "2023-07-29 18:35:46.434060") + LocalDateTime createdDate; + + @Schema(description = "만료 시간", example = "2024-01-29 18:35:46.434060") + LocalDateTime expiredDate; + public BrandDto(Brand brand, int stampCount) { + this.id = brand.getId(); + this.name = brand.getName(); + this.rewardDescription = brand.getRewardDescription(); + this.brandImageUrl = brand.getBrandImageUrl(); + this.stampCount = stampCount; + this.createdDate = brand.getCreatedDate(); + this.expiredDate = brand.getCreatedDate().plusMonths(6); + } +} diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java new file mode 100644 index 0000000..d059622 --- /dev/null +++ b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java @@ -0,0 +1,34 @@ +package com.example.couphoneserver.dto.member.response; + +import com.example.couphoneserver.domain.MemberGrade; +import com.example.couphoneserver.domain.MemberStatus; +import com.example.couphoneserver.domain.entity.Member; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; + +import java.util.List; + +@Getter +public class GetMemberCouponBrandsResponse { + @Schema(example = "1", description = "회원 아이디") + private Long id; + @Schema(example = "김이름", description = "회원 이름") + private String name; + @Schema(example = "aaa@naver.com", description = "이메일") + private String email; + @Schema(example = "ROLE_MEMBER", description = "회원 권한") + private MemberGrade memberGrade; + @Schema(example = "ACTIVE", description = "회원 상태") + private MemberStatus memberStatus; + @Schema(description = "회원 정보와, 회원이 가지고 있는 쿠폰에 대한 브랜드 목록을 반환") + private List brands; + + public GetMemberCouponBrandsResponse(Member member, List brands) { + this.id = member.getId(); + this.name = member.getName(); + this.email = member.getEmail(); + this.memberGrade = member.getGrade(); + this.memberStatus = member.getStatus(); + this.brands = brands; + } +} From a769c641684e8e10e0e329de833a9a6cd1ae00cc Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 16:11:41 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20?= =?UTF-8?q?=EC=86=8C=EC=9C=A0=ED=95=9C=20=EC=BF=A0=ED=8F=B0=EC=9D=98=20?= =?UTF-8?q?=EB=B8=8C=EB=9E=9C=EB=93=9C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20-=20Service=20=EA=B3=84=EC=B8=B5=20?= =?UTF-8?q?=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../couphoneserver/service/MemberService.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/main/java/com/example/couphoneserver/service/MemberService.java b/src/main/java/com/example/couphoneserver/service/MemberService.java index 0fad623..09ec567 100644 --- a/src/main/java/com/example/couphoneserver/service/MemberService.java +++ b/src/main/java/com/example/couphoneserver/service/MemberService.java @@ -3,11 +3,17 @@ import com.example.couphoneserver.common.exception.MemberException; import com.example.couphoneserver.domain.MemberGrade; import com.example.couphoneserver.domain.MemberStatus; +import com.example.couphoneserver.domain.entity.Brand; +import com.example.couphoneserver.domain.entity.CouponItem; import com.example.couphoneserver.domain.entity.Member; import com.example.couphoneserver.dto.auth.LoginRequestDto; import com.example.couphoneserver.dto.auth.LoginResponseDto; +import com.example.couphoneserver.dto.member.response.BrandDto; +import com.example.couphoneserver.dto.member.response.GetMemberCouponBrandsResponse; import com.example.couphoneserver.dto.member.response.GetMemberResponse; import com.example.couphoneserver.dto.member.response.PatchMemberResponse; +import com.example.couphoneserver.repository.BrandRepository; +import com.example.couphoneserver.repository.CouponItemRepository; import com.example.couphoneserver.repository.MemberRepository; import com.example.couphoneserver.utils.jwt.JwtTokenProvider; import lombok.RequiredArgsConstructor; @@ -37,6 +43,9 @@ @RequiredArgsConstructor public class MemberService { private final MemberRepository memberRepository; + private final CouponItemRepository couponItemRepository; + + private final BrandRepository brandRepository; private final BCryptPasswordEncoder bCryptPasswordEncoder; private final JwtTokenProvider jwtProvider; private final AuthenticationManagerBuilder authenticationManagerBuilder; @@ -170,4 +179,31 @@ public Optional getMemberByEmail(String email) { } + public GetMemberCouponBrandsResponse getBrands(Long memberId, int option) { + // 회원이 가지고 있는 쿠폰의 브랜드 정보 리스트와 회원 정보를 같이 반환합니다. + // 이때 정렬 기준은 option 에 따라서 달라집니다. (default 는 쿠폰 많은 순, 생성시간 이른 순) + List coupons; + switch (option) { + case 2 -> { + log.info("[정렬 필터 옵션2번]"); + coupons = couponItemRepository.findByMemberIdOrderByCreatedDateAndStampCount(memberId); + } + case 3 -> { + log.info("[정렬 필터 옵션3번]"); + coupons = couponItemRepository.findByMemberIdOrderByBrandName(memberId); + } + default -> { + log.info("[정렬 필터 옵션1번]"); + coupons = couponItemRepository.findByMemberIdOrderByStampCountAndCreatedDate(memberId); + } + } + List brands = coupons.stream().map(coupon -> { + Brand brand = coupon.getBrand(); + return new BrandDto(brand, coupon.getStampCount()); + }).toList(); + + Member member = findOneById(memberId); + return new GetMemberCouponBrandsResponse(member, brands); + } + } \ No newline at end of file From 6c0ed01bd1e62e7b6a21086f7ebfae0e05de8840 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 16:12:02 +0900 Subject: [PATCH 08/11] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EC=9D=B4=20?= =?UTF-8?q?=EC=86=8C=EC=9C=A0=ED=95=9C=20=EC=BF=A0=ED=8F=B0=EC=9D=98=20?= =?UTF-8?q?=EB=B8=8C=EB=9E=9C=EB=93=9C=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20-=20Controller=20=EA=B3=84=EC=B8=B5?= =?UTF-8?q?=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MemberController.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/java/com/example/couphoneserver/controller/MemberController.java b/src/main/java/com/example/couphoneserver/controller/MemberController.java index 6803daf..d192788 100644 --- a/src/main/java/com/example/couphoneserver/controller/MemberController.java +++ b/src/main/java/com/example/couphoneserver/controller/MemberController.java @@ -2,6 +2,7 @@ import com.example.couphoneserver.common.response.BaseResponse; import com.example.couphoneserver.domain.entity.Member; +import com.example.couphoneserver.dto.member.response.GetMemberCouponBrandsResponse; import com.example.couphoneserver.dto.member.response.GetMemberResponse; import com.example.couphoneserver.dto.member.response.PatchMemberResponse; import com.example.couphoneserver.service.MemberService; @@ -34,4 +35,19 @@ public BaseResponse show(@PathVariable("member-id") Long memb Member member = memberService.findOneById(memberId); return new BaseResponse<>(memberService.getMemberInfo(member)); } + + @GetMapping("/{member-id}/brands") + @Operation(summary = "정렬 조건에 따른 브랜드 조회", description = + """ + path variable 으로 member-id 를 보내면 해당 회원이 가지고 있는 쿠폰 브랜드 리스트를 반환합니다. + 정렬 조건은 query string 으로 sort 값을 보내주세요. {1, 2, 3} 에 따라 달라집니다. + - 1(default)번 옵션은 쿠폰 많은 순, 생성 시간이 이른 순 + - 2번 옵션은 생성 시간이 이른 순, 쿠폰 많은 순 + - 3번 옵션은 브랜드 이름 순으로 정렬하여 데이터를 반환합니다. + """) + public BaseResponse getBrands( + @PathVariable("member-id") Long memberId, + @RequestParam(required = false, defaultValue = "1", value = "sort") String sort) { + return new BaseResponse<>(memberService.getBrands(memberId, Integer.parseInt(sort))); + } } From f71b1dd69efff1c085cccba07de7cf33390ca690 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 18:55:09 +0900 Subject: [PATCH 09/11] =?UTF-8?q?feat:=20=EB=A7=8C=EB=A3=8C=EB=90=9C=20?= =?UTF-8?q?=EC=BF=A0=ED=8F=B0=EC=9D=80=20=EC=BF=BC=EB=A6=AC=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=A0=9C=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/CouponItemRepository.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java b/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java index c333b53..55da191 100644 --- a/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java +++ b/src/main/java/com/example/couphoneserver/repository/CouponItemRepository.java @@ -21,16 +21,15 @@ public interface CouponItemRepository extends JpaRepository { Optional findById(Long couponId); - // [Note] 만료일이 아니라 생성일로 정렬한 이유는, 만료일은 생성일+6M 이기 때문에 똑같다고 생각했기 떄문입니다. - // 특정 회원이 가지고 있는 쿠폰을 1. 도장 개수 많은 순, 2. 생성시간이 빠른 순으로 조회. - @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.stampCount DESC, c.createdDate ASC") + // 특정 회원이 가지고 있는 유효한 쿠폰을 1. 도장 개수 많은 순, 2. 생성시간이 빠른 순으로 조회. + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId AND c.status <> 'EXPIRED' ORDER BY c.stampCount DESC, c.createdDate ASC") List findByMemberIdOrderByStampCountAndCreatedDate(@Param("memberId") Long memberId); - // 특정 회원이 가지고 있는 쿠폰을 1. 생성시간이 빠른 순, 2. 도장 개수가 많은 순으로 조회. - @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.createdDate, c.stampCount DESC") + // 특정 회원이 가지고 있는 유효한 쿠폰을 1. 생성시간이 빠른 순, 2. 도장 개수가 많은 순으로 조회. + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId AND c.status <> 'EXPIRED' ORDER BY c.createdDate, c.stampCount DESC") List findByMemberIdOrderByCreatedDateAndStampCount(@Param("memberId") Long memberId); - // 특정 회원이 가지고 있는 쿠폰을 브랜드 이름으로 조회 - @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId ORDER BY c.brand.name") + // 특정 회원이 가지고 있는 유효한 쿠폰을 브랜드 이름으로 조회 + @Query("SELECT c FROM CouponItem c WHERE c.member.id = :memberId AND c.status <> 'EXPIRED' ORDER BY c.brand.name") List findByMemberIdOrderByBrandName(@Param("memberId") Long memberId); } From 6a2e9c961e65fb702f99c745e688ff3afabf61a5 Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Thu, 3 Aug 2023 18:55:58 +0900 Subject: [PATCH 10/11] =?UTF-8?q?feat:=20=EC=BF=A0=ED=8F=B0=EC=9D=98=20?= =?UTF-8?q?=EC=83=81=ED=83=9C=EB=8F=84=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD=20-=20{=20INACTIVE,=20A?= =?UTF-8?q?CTIVE=20}?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../couphoneserver/dto/member/response/BrandDto.java | 6 +++++- .../com/example/couphoneserver/service/MemberService.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java index 33a0ae6..05f59ae 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java +++ b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java @@ -1,5 +1,6 @@ package com.example.couphoneserver.dto.member.response; +import com.example.couphoneserver.domain.CouponItemStatus; import com.example.couphoneserver.domain.entity.Brand; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -23,12 +24,14 @@ public class BrandDto { @Schema(description = "스탬프 적립 개수", example = "3") int stampCount; + @Schema(description = "쿠폰 상태", example = "ACTIVE") + CouponItemStatus couponItemStatus; @Schema(description = "생성 시간", example = "2023-07-29 18:35:46.434060") LocalDateTime createdDate; @Schema(description = "만료 시간", example = "2024-01-29 18:35:46.434060") LocalDateTime expiredDate; - public BrandDto(Brand brand, int stampCount) { + public BrandDto(Brand brand, int stampCount, CouponItemStatus status) { this.id = brand.getId(); this.name = brand.getName(); this.rewardDescription = brand.getRewardDescription(); @@ -36,5 +39,6 @@ public BrandDto(Brand brand, int stampCount) { this.stampCount = stampCount; this.createdDate = brand.getCreatedDate(); this.expiredDate = brand.getCreatedDate().plusMonths(6); + this.couponItemStatus = status; } } diff --git a/src/main/java/com/example/couphoneserver/service/MemberService.java b/src/main/java/com/example/couphoneserver/service/MemberService.java index 09ec567..68c8d90 100644 --- a/src/main/java/com/example/couphoneserver/service/MemberService.java +++ b/src/main/java/com/example/couphoneserver/service/MemberService.java @@ -199,7 +199,7 @@ public GetMemberCouponBrandsResponse getBrands(Long memberId, int option) { } List brands = coupons.stream().map(coupon -> { Brand brand = coupon.getBrand(); - return new BrandDto(brand, coupon.getStampCount()); + return new BrandDto(brand, coupon.getStampCount(), coupon.getStatus()); }).toList(); Member member = findOneById(memberId); From 874ccbb21feaf370fb0f902336e066533d5b903b Mon Sep 17 00:00:00 2001 From: versatile0010 Date: Fri, 4 Aug 2023 17:15:19 +0900 Subject: [PATCH 11/11] refactor: BrandDto --- .../dto/member/response/BrandDto.java | 32 ++++--------------- .../GetMemberCouponBrandsResponse.java | 6 ++-- .../couphoneserver/service/MemberService.java | 6 ++-- 3 files changed, 12 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java index 05f59ae..eaaed96 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java +++ b/src/main/java/com/example/couphoneserver/dto/member/response/BrandDto.java @@ -1,7 +1,7 @@ package com.example.couphoneserver.dto.member.response; import com.example.couphoneserver.domain.CouponItemStatus; -import com.example.couphoneserver.domain.entity.Brand; +import com.example.couphoneserver.dto.brand.GetBrandResponse; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Getter; @@ -9,36 +9,16 @@ @Getter public class BrandDto { - @Schema(description = "브랜드 ID", example = "1") - Long id; - - @Schema(description = "브랜드 이름", example = "메가커피") - String name; - - @Schema(description = "보상 방법 (쿠폰 혜택)", example = "아이스 아메리카노 1잔 무료") - String rewardDescription; - - @Schema(description = "브랜드 로고 URL", example = "----") - String brandImageUrl; - - @Schema(description = "스탬프 적립 개수", example = "3") - int stampCount; - + @Schema(description = "브랜드 정보") + GetBrandResponse brandInfo; @Schema(description = "쿠폰 상태", example = "ACTIVE") CouponItemStatus couponItemStatus; - @Schema(description = "생성 시간", example = "2023-07-29 18:35:46.434060") - LocalDateTime createdDate; - @Schema(description = "만료 시간", example = "2024-01-29 18:35:46.434060") LocalDateTime expiredDate; - public BrandDto(Brand brand, int stampCount, CouponItemStatus status) { - this.id = brand.getId(); - this.name = brand.getName(); - this.rewardDescription = brand.getRewardDescription(); - this.brandImageUrl = brand.getBrandImageUrl(); - this.stampCount = stampCount; - this.createdDate = brand.getCreatedDate(); + + public BrandDto(GetBrandResponse brand, CouponItemStatus status) { this.expiredDate = brand.getCreatedDate().plusMonths(6); this.couponItemStatus = status; + this.brandInfo = brand; } } diff --git a/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java index d059622..10df028 100644 --- a/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java +++ b/src/main/java/com/example/couphoneserver/dto/member/response/GetMemberCouponBrandsResponse.java @@ -21,14 +21,14 @@ public class GetMemberCouponBrandsResponse { @Schema(example = "ACTIVE", description = "회원 상태") private MemberStatus memberStatus; @Schema(description = "회원 정보와, 회원이 가지고 있는 쿠폰에 대한 브랜드 목록을 반환") - private List brands; + private List brandInfoList; - public GetMemberCouponBrandsResponse(Member member, List brands) { + public GetMemberCouponBrandsResponse(Member member, List brandsInfoList) { this.id = member.getId(); this.name = member.getName(); this.email = member.getEmail(); this.memberGrade = member.getGrade(); this.memberStatus = member.getStatus(); - this.brands = brands; + this.brandInfoList= brandsInfoList; } } diff --git a/src/main/java/com/example/couphoneserver/service/MemberService.java b/src/main/java/com/example/couphoneserver/service/MemberService.java index 68c8d90..b205003 100644 --- a/src/main/java/com/example/couphoneserver/service/MemberService.java +++ b/src/main/java/com/example/couphoneserver/service/MemberService.java @@ -3,11 +3,11 @@ import com.example.couphoneserver.common.exception.MemberException; import com.example.couphoneserver.domain.MemberGrade; import com.example.couphoneserver.domain.MemberStatus; -import com.example.couphoneserver.domain.entity.Brand; import com.example.couphoneserver.domain.entity.CouponItem; import com.example.couphoneserver.domain.entity.Member; import com.example.couphoneserver.dto.auth.LoginRequestDto; import com.example.couphoneserver.dto.auth.LoginResponseDto; +import com.example.couphoneserver.dto.brand.GetBrandResponse; import com.example.couphoneserver.dto.member.response.BrandDto; import com.example.couphoneserver.dto.member.response.GetMemberCouponBrandsResponse; import com.example.couphoneserver.dto.member.response.GetMemberResponse; @@ -198,8 +198,8 @@ public GetMemberCouponBrandsResponse getBrands(Long memberId, int option) { } } List brands = coupons.stream().map(coupon -> { - Brand brand = coupon.getBrand(); - return new BrandDto(brand, coupon.getStampCount(), coupon.getStatus()); + GetBrandResponse brandInfo = new GetBrandResponse(coupon.getBrand(), coupon.getStampCount()); + return new BrandDto(brandInfo, coupon.getStatus()); }).toList(); Member member = findOneById(memberId);