Skip to content

Commit

Permalink
Feat: 마음 구매 API 추가 (#61)
Browse files Browse the repository at this point in the history
* Feat(#51): 후원 관련 엔티티 칼럼 설정 및 엔티티간 매핑

* Feat(#51): 커스텀 예외 설정

* Feat(#51): 후원 및 응원 api 개발

* Feat(#51): 후원 및 응원 관련 dto 작성

* Feat(#51): 후원 홈 목록 조회 관련 API 개발

* Feat(#51): 이미지, 후원사URL 데이터 추가

* Feat(#51): swagger 설명 추가

* Refactor(#51): Support 객체 생성 부분 리팩토링

* Refactor(#51): 이미지 변수명 변경

* Feat(#51): 마음 결제 API 구현

* Feat(#51): 후원시 사용자의 마음 갯수 반영

* Refactor(#51): 네이밍 변경 및 커스텀 예외 추가

* Refactor(#51): dto 폴더 위치 오류 수정

* Rename(#51): 폴더명 오타 수정
  • Loading branch information
nohy6630 authored Nov 15, 2023
1 parent 51f9086 commit f3d9922
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.numberone.backend.domain.member.controller;

import com.numberone.backend.domain.member.dto.request.BuyHeartRequest;
import com.numberone.backend.domain.member.dto.response.HeartCntResponse;
import com.numberone.backend.domain.member.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 org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;

@Tag(name = "members", description = "사용자 관련 API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/members")
public class MemberController {
private final MemberService memberService;

@PostMapping("/heart")
@Operation(summary = "마음 구입하기", description = """
구입한 마음 갯수를 body에 담아 전달해주세요.
response 에는 구입한 후에 사용자의 현재 마음 갯수가 저장되어 있습니다.
""")
public ResponseEntity<HeartCntResponse> buyHeart(@RequestBody @Valid BuyHeartRequest buyHeartRequest, Authentication authentication) {
return ResponseEntity.status(HttpStatus.CREATED).body(memberService.buyHeart(buyHeartRequest, authentication.getName()));
}

@GetMapping("/heart")
@Operation(summary = "사용자의 현재 마음 갯수 가져오기", description = """
사용자의 현재 마음 갯수가 response로 전달됩니다.
""")
public ResponseEntity<HeartCntResponse> getHeart(Authentication authentication) {
return ResponseEntity.ok(memberService.getHeart(authentication.getName()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.numberone.backend.domain.member.dto.request;

import jakarta.validation.constraints.NotNull;
import lombok.*;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class BuyHeartRequest {
@NotNull(message = "구입한 마음 갯수를 입력해주세요")
private Integer heartCnt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.numberone.backend.domain.member.dto.response;

import com.numberone.backend.domain.member.entity.Member;
import lombok.*;

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
@AllArgsConstructor
@Builder
public class HeartCntResponse {
private Integer heartCnt;

public static HeartCntResponse of(Member member) {
return HeartCntResponse.builder()
.heartCnt(member.getHeartCnt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,23 @@ public class Member {
private List<Support> supports = new ArrayList<>();

@Builder
public Member(String email) {
public Member(String email, Integer heartCnt) {
this.email = email;
this.heartCnt = heartCnt;
}

public static Member of(String email){
public static Member of(String email) {
return Member.builder()
.email(email)
.heartCnt(0)
.build();
}

public void plusHeart(int heart) {
heartCnt += heart;
}

public void minusHeart(int heart) {
heartCnt -= heart;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.numberone.backend.domain.member.service;

import com.numberone.backend.domain.member.dto.request.BuyHeartRequest;
import com.numberone.backend.domain.member.dto.response.HeartCntResponse;
import com.numberone.backend.domain.member.entity.Member;
import com.numberone.backend.domain.member.repository.MemberRepository;
import com.numberone.backend.exception.notfound.NotFoundMemberException;
Expand All @@ -22,4 +24,18 @@ public Member findByEmail(String email) {
public void create(String email) {
memberRepository.save(Member.of(email));
}

@Transactional
public HeartCntResponse buyHeart(BuyHeartRequest buyHeartRequest, String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(NotFoundMemberException::new);
member.plusHeart(buyHeartRequest.getHeartCnt());
return HeartCntResponse.of(member);
}

public HeartCntResponse getHeart(String email) {
Member member = memberRepository.findByEmail(email)
.orElseThrow(NotFoundMemberException::new);
return HeartCntResponse.of(member);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.numberone.backend.domain.support.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;

@Getter
Expand All @@ -9,7 +10,7 @@
public class CreateSupportResponse {
private Long supportId;

public static CreateSupportResponse of(Long supportId){
public static CreateSupportResponse of(Long supportId) {
return CreateSupportResponse.builder()
.supportId(supportId)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@
import com.numberone.backend.domain.support.dto.response.CreateSupportResponse;
import com.numberone.backend.domain.support.entity.Support;
import com.numberone.backend.domain.support.repository.SupportRepository;
import com.numberone.backend.exception.badrequest.BadRequestHeartException;
import com.numberone.backend.exception.notfound.NotFoundMemberException;
import com.numberone.backend.exception.notfound.NotFoundSupportException;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -38,10 +37,13 @@ public CreateSupportResponse create(CreateSupportRequest createSupportRequest, S
.orElseThrow(NotFoundSupportException::new);
Member member = memberRepository.findByEmail(email)
.orElseThrow(NotFoundMemberException::new);
if (member.getHeartCnt() < createSupportRequest.getHeartCnt())
throw new BadRequestHeartException();
Support support = Support.of(
sponsor,
member
);
member.minusHeart(createSupportRequest.getHeartCnt());
sponsor.increaseHeart(createSupportRequest.getHeartCnt());
support = supportRepository.save(support);
return CreateSupportResponse.of(support.getId());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.numberone.backend.exception.badrequest;

import com.numberone.backend.exception.context.ExceptionContext;

import static com.numberone.backend.exception.context.CustomExceptionContext.BAD_REQUEST_HEART;

public class BadRequestHeartException extends BadRequestException{

public BadRequestHeartException() {
super(BAD_REQUEST_HEART);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public enum CustomExceptionContext implements ExceptionContext {

//후원 페이지 관련 예외
NOT_FOUND_SUPPORT("존재하지 않는 후원 관계입니다.", 7000),
NOT_FOUND_SPONSOR("존재하지 않는 후원입니다.", 7001)
NOT_FOUND_SPONSOR("존재하지 않는 후원입니다.", 7001),
BAD_REQUEST_HEART("후원을 하기에는 사용자의 마음 갯수가 부족합니다.",7002)
;

private final String message;
Expand Down

0 comments on commit f3d9922

Please sign in to comment.