From 600906f7e2f56c831e7e1f6fe2881734fa9831d8 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Wed, 8 May 2024 22:39:25 +0900 Subject: [PATCH 01/15] =?UTF-8?q?#2=20Feat:=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gifticionfunding/domain/FriendKey.java | 11 ++++++++++ .../domain/FriendRequest.java | 21 +++++++++++++++++++ .../gifticionfunding/domain/Friendship.java | 9 ++++++++ .../domain/enums/FriendStatus.java | 5 +++++ 4 files changed, 46 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/Friendship.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/enums/FriendStatus.java diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java b/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java new file mode 100644 index 0000000..beab314 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java @@ -0,0 +1,11 @@ +package team.haedal.gifticionfunding.domain; + +import jakarta.persistence.Embeddable; + +import java.io.Serializable; + +@Embeddable +public class FriendKey implements Serializable { + private Long member; + private Long friend; +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java b/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java new file mode 100644 index 0000000..47600fa --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java @@ -0,0 +1,21 @@ +package team.haedal.gifticionfunding.domain; + +import jakarta.persistence.*; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +import java.time.LocalDateTime; + +@Entity +public class FriendRequest { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Member sender; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Member receiver; + private LocalDateTime createdAt; +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java new file mode 100644 index 0000000..15e8f1b --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java @@ -0,0 +1,9 @@ +package team.haedal.gifticionfunding.domain; + +import jakarta.persistence.*; + +@Entity +public class Friendship { + @EmbeddedId + private FriendKey friendKey; +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/enums/FriendStatus.java b/src/main/java/team/haedal/gifticionfunding/domain/enums/FriendStatus.java new file mode 100644 index 0000000..81fc522 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/enums/FriendStatus.java @@ -0,0 +1,5 @@ +package team.haedal.gifticionfunding.domain.enums; + +public enum FriendStatus { + ACCEPT, WAITING +} From 2eec747ae00d4fc21756ad8a2eb573a43936b58c Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Wed, 8 May 2024 22:39:49 +0900 Subject: [PATCH 02/15] =?UTF-8?q?#2=20Feat:=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FriendController.java | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/controller/FriendController.java diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java new file mode 100644 index 0000000..95e13e5 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java @@ -0,0 +1,52 @@ +package team.haedal.gifticionfunding.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +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.*; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@RestController +@RequiredArgsConstructor +@EnableWebMvc +@RequestMapping("/api/friend") +@Tag(name="Friend",description="친구 관련 API") +public class FriendController { + @GetMapping() + @Operation(summary = "친구 목록 조회 API") + public ResponseEntity getFriends(Authentication authentication){ + return ResponseEntity.status(HttpStatus.OK).body(null); + } + + @PostMapping("/request") + @Operation(summary = "친구 요청 API") + public ResponseEntity requestFriend(Authentication authentication, + @RequestParam(name="friend") Long id){ + return ResponseEntity.status(HttpStatus.CREATED).body(null); + } + + @PostMapping("/accept") + @Operation(summary = "친구 수락 API") + public ResponseEntity acceptFriend(Authentication authentication, + @RequestParam(name="friend") Long id){ + return ResponseEntity.status(HttpStatus.CREATED).body(null); + } + + @PostMapping("/reject") + @Operation(summary = "친구 거절 API") + public ResponseEntity rejectFriend(Authentication authentication, + @RequestParam(name="friend") Long id){ + return ResponseEntity.status(HttpStatus.OK).body(null); + } + + @GetMapping("/request") + @Operation(summary = "친구 요청 조회 API") + public ResponseEntity getRequestedFriends(Authentication authentication){ + return ResponseEntity.status(HttpStatus.OK).body(null); + } + + +} From 6068220d6f196376604ef7198fb7bca21f4e8f1b Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Wed, 8 May 2024 22:40:58 +0900 Subject: [PATCH 03/15] =?UTF-8?q?#2=20Docs:=20swagger=20Authorization=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gifticionfunding/config/SecurityConfig.java | 4 +--- .../gifticionfunding/config/SwaggerConfig.java | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/config/SecurityConfig.java b/src/main/java/team/haedal/gifticionfunding/config/SecurityConfig.java index 44151aa..f241fd6 100644 --- a/src/main/java/team/haedal/gifticionfunding/config/SecurityConfig.java +++ b/src/main/java/team/haedal/gifticionfunding/config/SecurityConfig.java @@ -26,9 +26,7 @@ public class SecurityConfig { private static final String[] WHITE_LIST = { - "/api/auth/**", - "/api-docs/**", - "/login/**", + "**" }; private static final String[] AUTHENTICATION_LIST = { diff --git a/src/main/java/team/haedal/gifticionfunding/config/SwaggerConfig.java b/src/main/java/team/haedal/gifticionfunding/config/SwaggerConfig.java index 57995a4..4b21c17 100644 --- a/src/main/java/team/haedal/gifticionfunding/config/SwaggerConfig.java +++ b/src/main/java/team/haedal/gifticionfunding/config/SwaggerConfig.java @@ -3,6 +3,8 @@ import io.swagger.v3.oas.models.Components; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -10,9 +12,18 @@ public class SwaggerConfig { @Bean public OpenAPI openAPI() { + String jwt = "accessToken"; + SecurityRequirement securityRequirement = new SecurityRequirement().addList(jwt); + Components components = new Components().addSecuritySchemes(jwt, new SecurityScheme() + .name(jwt) + .type(SecurityScheme.Type.HTTP) + .scheme("bearer") + .bearerFormat("JWT") + ); return new OpenAPI() - .components(new Components()) - .info(apiInfo()); + .components(components) + .info(apiInfo()) + .addSecurityItem(securityRequirement); } private Info apiInfo() { From 6a48b49b7fd1de73d12588db6aaa54477fbc5175 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Thu, 9 May 2024 16:27:15 +0900 Subject: [PATCH 04/15] =?UTF-8?q?#2=20Feat:=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- .../controller/FriendController.java | 33 ++++--- .../gifticionfunding/exception/ErrorCode.java | 3 +- .../service/FriendService.java | 90 +++++++++++++++++++ 4 files changed, 116 insertions(+), 14 deletions(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/service/FriendService.java diff --git a/.gitignore b/.gitignore index 29fffdc..d7bf230 100644 --- a/.gitignore +++ b/.gitignore @@ -36,4 +36,6 @@ out/ ### VS Code ### .vscode/ src/main/resources/application.yml -src/main/java/team/haedal/gifticionfunding/service/OAuth2SuccessHandler.java \ No newline at end of file +src/main/java/team/haedal/gifticionfunding/service/OAuth2SuccessHandler.java +src/main/resources/data.sql +src/main/java/team/haedal/gifticionfunding/jwt/** \ No newline at end of file diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java index 95e13e5..66a6a73 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java @@ -8,6 +8,9 @@ import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import team.haedal.gifticionfunding.dto.PageResponse; +import team.haedal.gifticionfunding.dto.response.friend.FriendResponse; +import team.haedal.gifticionfunding.service.FriendService; @RestController @RequiredArgsConstructor @@ -15,37 +18,43 @@ @RequestMapping("/api/friend") @Tag(name="Friend",description="친구 관련 API") public class FriendController { + //TODO: 친구 목록, 요청받은 친구 목록 + //TODO: 친구 요청, 요청 수락, 요청 거절, 요청 취소 + private final FriendService friendService; + @GetMapping() @Operation(summary = "친구 목록 조회 API") - public ResponseEntity getFriends(Authentication authentication){ - return ResponseEntity.status(HttpStatus.OK).body(null); + public ResponseEntity> getFriends(Authentication authentication, + @RequestParam(value="page", defaultValue="0") int page){ + return ResponseEntity.status(HttpStatus.OK).body(friendService.getFriends(page,authentication.getName())); } @PostMapping("/request") @Operation(summary = "친구 요청 API") - public ResponseEntity requestFriend(Authentication authentication, + public void requestFriend(Authentication authentication, @RequestParam(name="friend") Long id){ - return ResponseEntity.status(HttpStatus.CREATED).body(null); + System.out.println(authentication.getDetails().toString()); + friendService.requestFriend(authentication.getName(),id); } @PostMapping("/accept") @Operation(summary = "친구 수락 API") - public ResponseEntity acceptFriend(Authentication authentication, + public void acceptFriend(Authentication authentication, @RequestParam(name="friend") Long id){ - return ResponseEntity.status(HttpStatus.CREATED).body(null); - } + friendService.acceptFriend(authentication.getName(),id); } @PostMapping("/reject") @Operation(summary = "친구 거절 API") - public ResponseEntity rejectFriend(Authentication authentication, + public void rejectFriend(Authentication authentication, @RequestParam(name="friend") Long id){ - return ResponseEntity.status(HttpStatus.OK).body(null); + friendService.rejectFriend(authentication.getName(),id); } @GetMapping("/request") - @Operation(summary = "친구 요청 조회 API") - public ResponseEntity getRequestedFriends(Authentication authentication){ - return ResponseEntity.status(HttpStatus.OK).body(null); + @Operation(summary = "친구 요청 조회 API", description ="수락 대기중인 요청만 나타낸다.") + public ResponseEntity> getRequestedFriends(Authentication authentication, + @RequestParam(value="page", defaultValue="0") int page){ + return ResponseEntity.status(HttpStatus.OK).body(friendService.getRequestedFriends(page, authentication.getName())); } diff --git a/src/main/java/team/haedal/gifticionfunding/exception/ErrorCode.java b/src/main/java/team/haedal/gifticionfunding/exception/ErrorCode.java index 82db847..7bec815 100644 --- a/src/main/java/team/haedal/gifticionfunding/exception/ErrorCode.java +++ b/src/main/java/team/haedal/gifticionfunding/exception/ErrorCode.java @@ -13,7 +13,8 @@ public enum ErrorCode { NOT_FOUND(404,HttpStatus.NOT_FOUND, "데이터를 찾을 수 없습니다"), INVALID_PERMISSION(401,HttpStatus.UNAUTHORIZED, "권한이 없습니다"), - INVALID_INPUT(400, HttpStatus.BAD_REQUEST,"잘못된 요청입니다."); + INVALID_INPUT(400, HttpStatus.BAD_REQUEST,"잘못된 요청입니다."), + USER_NOT_FOUND(400,HttpStatus.BAD_REQUEST,"사용자를 찾을 수 없습니다."); private int status; private HttpStatus error; private String message; diff --git a/src/main/java/team/haedal/gifticionfunding/service/FriendService.java b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java new file mode 100644 index 0000000..979075d --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java @@ -0,0 +1,90 @@ +package team.haedal.gifticionfunding.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import team.haedal.gifticionfunding.domain.Friendship; +import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.domain.enums.FriendStatus; +import team.haedal.gifticionfunding.dto.PageResponse; +import team.haedal.gifticionfunding.dto.response.friend.FriendResponse; +import team.haedal.gifticionfunding.exception.CustomException; +import team.haedal.gifticionfunding.exception.ErrorCode; +import team.haedal.gifticionfunding.repository.dao.FriendOnly; +import team.haedal.gifticionfunding.repository.FriendRepository; +import team.haedal.gifticionfunding.repository.dao.MemberOnly; +import team.haedal.gifticionfunding.repository.MemberRepository; + +import java.util.stream.Collectors; + + +@Service +@RequiredArgsConstructor +public class FriendService { + private final MemberRepository memberRepository; + private final FriendRepository friendRepository; + + + @Transactional(readOnly = true) + public PageResponse getFriends(int page, String name){ + Member member = memberRepository.getUserByEmail(name); + Page pageData = friendRepository.findAllByMemberAndStatus(PageRequest.of(page, 10), member, FriendStatus.ACCEPT); + + return PageResponse.builder() + .content(pageData.getContent().stream() + .map(data -> FriendResponse.from(data.getFriend())) + .collect(Collectors.toList())) + .page(pageData.getNumber()) + .isLast(pageData.isLast()) + .build(); + } + + + @Transactional() + public void requestFriend(String name, Long friendId){ + Member sender = memberRepository.getUserByEmail(name); + Member receiver = memberRepository.getUserById(friendId); + + friendRepository.save(Friendship.request(sender,receiver)); + } + + + @Transactional() + public void acceptFriend(String name, Long friendId){ + Member receiver = memberRepository.getUserByEmail(name); + Member sender = memberRepository.getUserById(friendId); + Friendship friendship = friendRepository.findByMemberAndFriend(sender, receiver) + .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + friendship.accept(); + friendRepository.save(Friendship.finish(receiver,sender)); + } + + + @Transactional() + public void rejectFriend(String name, Long friendId){ + Member receiver = memberRepository.getUserByEmail(name); + Friendship friendship = friendRepository.findByMemberAndFriend(friendId, receiver.getId()) + .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); + + // friendship에 접근할때 sender를 조회하기 위한 쿼리가 한번 더 나감 (N+1) + friendRepository.delete(friendship); + } + + + @Transactional(readOnly = true) + public PageResponse getRequestedFriends(int page, String name){ + Member receiver = memberRepository.getUserByEmail(name); + Page pageData = friendRepository.findAllByFriendAndStatus(PageRequest.of(page, 10), receiver, FriendStatus.WAITING); + + return PageResponse.builder() + .content(pageData.getContent().stream() + .map(data -> FriendResponse.from(data.getMember())) + .collect(Collectors.toList())) + .page(pageData.getNumber()) + .isLast(pageData.isLast()) + .build(); + } + +} From 0e8fa2ce8d9164e4db31e5215cf3e322c182217c Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Thu, 9 May 2024 16:31:41 +0900 Subject: [PATCH 05/15] =?UTF-8?q?#2=20Fix:=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FriendRequest을 없애고 Friendship에서 status를 관리하도록 수정 --- .../gifticionfunding/domain/FriendKey.java | 11 ---- .../domain/FriendRequest.java | 21 ------- .../gifticionfunding/domain/Friendship.java | 62 ++++++++++++++++++- .../gifticionfunding/domain/Member.java | 6 +- 4 files changed, 62 insertions(+), 38 deletions(-) delete mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java delete mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java b/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java deleted file mode 100644 index beab314..0000000 --- a/src/main/java/team/haedal/gifticionfunding/domain/FriendKey.java +++ /dev/null @@ -1,11 +0,0 @@ -package team.haedal.gifticionfunding.domain; - -import jakarta.persistence.Embeddable; - -import java.io.Serializable; - -@Embeddable -public class FriendKey implements Serializable { - private Long member; - private Long friend; -} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java b/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java deleted file mode 100644 index 47600fa..0000000 --- a/src/main/java/team/haedal/gifticionfunding/domain/FriendRequest.java +++ /dev/null @@ -1,21 +0,0 @@ -package team.haedal.gifticionfunding.domain; - -import jakarta.persistence.*; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; - -import java.time.LocalDateTime; - -@Entity -public class FriendRequest { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @ManyToOne() - @OnDelete(action = OnDeleteAction.CASCADE) - private Member sender; - @ManyToOne() - @OnDelete(action = OnDeleteAction.CASCADE) - private Member receiver; - private LocalDateTime createdAt; -} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java index 15e8f1b..3ae148b 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java @@ -1,9 +1,67 @@ package team.haedal.gifticionfunding.domain; import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; +import team.haedal.gifticionfunding.domain.enums.FriendStatus; + +import java.time.LocalDateTime; @Entity +@Getter +@NoArgsConstructor public class Friendship { - @EmbeddedId - private FriendKey friendKey; + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Member member; + + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Member friend; + + private LocalDateTime createdAt; + + @Enumerated(EnumType.STRING) + private FriendStatus status; + + @Builder + private Friendship(Long id, Member member, Member friend, LocalDateTime createdAt, FriendStatus status) { + this.id = id; + this.member = member; + this.friend = friend; + this.createdAt = createdAt; + this.status = status; + } + + public static Friendship request(Member member, Member friend) { + return Friendship.builder() + .member(member) + .friend(friend) + .createdAt(LocalDateTime.now()) + .status(FriendStatus.WAITING) + .build(); + } + + public static Friendship finish(Member member, Member friend) { + return Friendship.builder() + .member(member) + .friend(friend) + .createdAt(LocalDateTime.now()) + .status(FriendStatus.ACCEPT) + .build(); + } + + public Friendship accept(){ + this.status = FriendStatus.ACCEPT; + return this; + } + + } diff --git a/src/main/java/team/haedal/gifticionfunding/domain/Member.java b/src/main/java/team/haedal/gifticionfunding/domain/Member.java index 861ef85..9a9b166 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/Member.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/Member.java @@ -2,10 +2,7 @@ import jakarta.annotation.Nullable; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.NoArgsConstructor; +import lombok.*; import team.haedal.gifticionfunding.domain.enums.Role; import java.time.LocalDate; @@ -14,6 +11,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Builder +@Getter public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From 3ece524f42a450ea325aff011d3a07e9d9e4b486 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Thu, 9 May 2024 16:39:54 +0900 Subject: [PATCH 06/15] =?UTF-8?q?2=20Feat:=20=EC=B9=9C=EA=B5=AC=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A6=AC=ED=8F=AC=EC=A7=80=ED=8F=AC=EB=A6=AC=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 불필요한 정보를 제회하고 가져올 수 있도록 별도의 VO객체 정의 --- .../repository/FriendRepository.java | 25 +++++++++++++++++++ .../repository/MemberRepository.java | 12 +++++++++ .../repository/vo/FriendOnly.java | 7 ++++++ .../repository/vo/MemberOnly.java | 7 ++++++ 4 files changed, 51 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/vo/FriendOnly.java create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/vo/MemberOnly.java diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java new file mode 100644 index 0000000..a4ae275 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java @@ -0,0 +1,25 @@ +package team.haedal.gifticionfunding.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import team.haedal.gifticionfunding.domain.Friendship; +import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.domain.enums.FriendStatus; +import team.haedal.gifticionfunding.repository.vo.FriendOnly; +import team.haedal.gifticionfunding.repository.vo.MemberOnly; + +import java.util.Optional; + +public interface FriendRepository extends JpaRepository { + Page findAllByMemberAndStatus(Pageable pageable, Member member, FriendStatus status); + Page findAllByFriendAndStatus(Pageable pageable, Member friend, FriendStatus status); + + @Query(value = "select * from Friendship where member_id = :memberId and friend_id = :friendId", nativeQuery = true) + Optional findByMemberAndFriend(@Param("memberId") Long memberId, @Param("friendId") Long friendId); + + Optional findByMemberAndFriend(Member member, Member friend); + +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java index b9e339d..21a4847 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java @@ -2,9 +2,21 @@ import org.springframework.data.jpa.repository.JpaRepository; import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.exception.CustomException; +import team.haedal.gifticionfunding.exception.ErrorCode; import java.util.Optional; public interface MemberRepository extends JpaRepository { Optional findByNickname(String nickname); + + default Member getUserByEmail(String name) { + return this.findByNickname(name).orElseThrow( + () -> new CustomException(ErrorCode.USER_NOT_FOUND)); + } + + default Member getUserById(Long id) { + return this.findById(id).orElseThrow( + () -> new CustomException(ErrorCode.USER_NOT_FOUND)); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/repository/vo/FriendOnly.java b/src/main/java/team/haedal/gifticionfunding/repository/vo/FriendOnly.java new file mode 100644 index 0000000..ccd3db3 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/vo/FriendOnly.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository.vo; + +import team.haedal.gifticionfunding.domain.Member; + +public interface FriendOnly { + Member getFriend(); +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/vo/MemberOnly.java b/src/main/java/team/haedal/gifticionfunding/repository/vo/MemberOnly.java new file mode 100644 index 0000000..67a3d94 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/vo/MemberOnly.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository.vo; + +import team.haedal.gifticionfunding.domain.Member; + +public interface MemberOnly { + Member getMember(); +} From 0869f4e40f78560300a87a6522684b9669b51afa Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Thu, 9 May 2024 16:46:54 +0900 Subject: [PATCH 07/15] =?UTF-8?q?#2=20Feat:=20=EC=B9=9C=EA=B5=AC=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=95=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=9D=91=EB=8B=B5=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gifticionfunding/dto/PageResponse.java | 30 ++++++++++++++++ .../dto/response/friend/FriendResponse.java | 34 +++++++++++++++++++ 2 files changed, 64 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/PageResponse.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java diff --git a/src/main/java/team/haedal/gifticionfunding/dto/PageResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/PageResponse.java new file mode 100644 index 0000000..0814477 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/PageResponse.java @@ -0,0 +1,30 @@ +package team.haedal.gifticionfunding.dto; + +import lombok.Builder; +import lombok.Getter; +import org.springframework.data.domain.Page; + +import java.util.List; + +@Getter +public class PageResponse { + private List content; + private int page; + private boolean isLast; + + @Builder + private PageResponse(List content, int page, boolean isLast){ + this.content = content; + this.page = page; + this.isLast = isLast; + } + + public static PageResponse from(Page data){ + return PageResponse.builder() + .content(data.getContent()) + .page(data.getNumber()) + .isLast(data.isLast()) + .build(); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java new file mode 100644 index 0000000..11c9567 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java @@ -0,0 +1,34 @@ +package team.haedal.gifticionfunding.dto.response.friend; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import lombok.Builder; +import lombok.Getter; +import team.haedal.gifticionfunding.domain.Member; + +import java.time.LocalDate; + +@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) +@Getter +public class FriendResponse { + private Long id; + private String nickname; + private String profileImageUrl; + private LocalDate birthdate; + + @Builder + private FriendResponse(Long id, String nickname, String profileImageUrl, LocalDate birthdate){ + this.id = id; + this.nickname = nickname; + this.profileImageUrl = profileImageUrl; + this.birthdate = birthdate; + } + + public static FriendResponse from(Member member){ + return FriendResponse.builder() + .id(member.getId()) + .nickname(member.getNickname()) + .profileImageUrl(member.getProfileImageUrl()) + .birthdate(member.getBirthdate()) + .build(); + } +} From 8ad05126db22efca79fc6ec82b839c3d72111177 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Thu, 9 May 2024 16:47:44 +0900 Subject: [PATCH 08/15] =?UTF-8?q?#3=20Feat:=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=EC=9D=84=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=8A=A4=EC=BC=88=EB=A0=88=ED=86=A4=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +- .../controller/FundingController.java | 17 +++++++++ .../domain/FundingArticle.java | 37 +++++++++++++++++++ .../domain/FundingGifticon.java | 36 ++++++++++++++++++ .../gifticionfunding/jwt/JwtProvider.java | 2 +- .../service/FriendService.java | 4 +- 6 files changed, 94 insertions(+), 5 deletions(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/controller/FundingController.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java diff --git a/.gitignore b/.gitignore index d7bf230..1bd5099 100644 --- a/.gitignore +++ b/.gitignore @@ -37,5 +37,4 @@ out/ .vscode/ src/main/resources/application.yml src/main/java/team/haedal/gifticionfunding/service/OAuth2SuccessHandler.java -src/main/resources/data.sql -src/main/java/team/haedal/gifticionfunding/jwt/** \ No newline at end of file +src/main/resources/data.sql \ No newline at end of file diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java new file mode 100644 index 0000000..f33ae5a --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java @@ -0,0 +1,17 @@ +package team.haedal.gifticionfunding.controller; + +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +@RestController +@RequiredArgsConstructor +@EnableWebMvc +@RequestMapping("/api/funding") +@Tag(name="Funding",description="펀딩 관련 API") +public class FundingController { + //TODO: 가능한 펀딩 조회, 참여한 펀딩 조회, 생성한 펀딩 조회 + //TODO: 펀딩 생성 (유효하지 않은 기프티콘이 하나라도 포함된다면 전체 fail) +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java new file mode 100644 index 0000000..9e9a851 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java @@ -0,0 +1,37 @@ +package team.haedal.gifticionfunding.domain; + +import jakarta.persistence.*; +import lombok.Builder; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +import java.time.LocalDateTime; + +@Entity +@NoArgsConstructor +public class FundingArticle { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Member member; + private LocalDateTime createdAt; + private LocalDateTime endAt; + private String title; + @Column(length = 50000) + private String content; + + @Builder + private FundingArticle(Long id, Member member, LocalDateTime createdAt, LocalDateTime endAt, String title, String content){ + this.id = id; + this.member = member; + this.createdAt = createdAt; + this.endAt = endAt; + this.title = title; + this.content = content; + } + +// public static FundingArticle +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java new file mode 100644 index 0000000..98e37c4 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java @@ -0,0 +1,36 @@ +package team.haedal.gifticionfunding.domain; + +import jakarta.persistence.*; +import lombok.Builder; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; + +@Entity +@NoArgsConstructor +public class FundingGifticon { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private Gifticon gifticon; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + private FundingArticle fundingArticle; + + @Builder + private FundingGifticon(Long id, Gifticon gifticon, FundingArticle fundingArticle){ + this.id = id; + this.fundingArticle = fundingArticle; + this.gifticon = gifticon; + } + + public static FundingGifticon of(Gifticon gifticon, FundingArticle fundingArticle){ + return FundingGifticon.builder() + .gifticon(gifticon) + .fundingArticle(fundingArticle) + .build(); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/jwt/JwtProvider.java b/src/main/java/team/haedal/gifticionfunding/jwt/JwtProvider.java index f9d0f0d..03f75c5 100644 --- a/src/main/java/team/haedal/gifticionfunding/jwt/JwtProvider.java +++ b/src/main/java/team/haedal/gifticionfunding/jwt/JwtProvider.java @@ -12,7 +12,7 @@ public class JwtProvider { @Value("${jwt.secret}") private String secretKey; - private static final long ACCESS_TOKEN_EXPIRE_TIME = 1000 * 60 * 30; + private static final long ACCESS_TOKEN_EXPIRE_TIME = 1000 * 60 * 30000; private static final long REFRESH_TOKEN_EXPIRE_TIME = 1000 * 60 * 60 * 24 * 7; private String createAccessToken(String memberId){ diff --git a/src/main/java/team/haedal/gifticionfunding/service/FriendService.java b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java index 979075d..a4ff871 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FriendService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java @@ -12,9 +12,9 @@ import team.haedal.gifticionfunding.dto.response.friend.FriendResponse; import team.haedal.gifticionfunding.exception.CustomException; import team.haedal.gifticionfunding.exception.ErrorCode; -import team.haedal.gifticionfunding.repository.dao.FriendOnly; +import team.haedal.gifticionfunding.repository.vo.FriendOnly; import team.haedal.gifticionfunding.repository.FriendRepository; -import team.haedal.gifticionfunding.repository.dao.MemberOnly; +import team.haedal.gifticionfunding.repository.vo.MemberOnly; import team.haedal.gifticionfunding.repository.MemberRepository; import java.util.stream.Collectors; From 5b35aea58e2bdfcb63a08b6d03fc7b1d34e9a9ca Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:51:24 +0900 Subject: [PATCH 09/15] =?UTF-8?q?Feat:=20exception=20=EB=A9=94=EC=84=B8?= =?UTF-8?q?=EC=A7=80=20=EC=A0=95=EC=9D=98=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=83=9D=EC=84=B1=EC=9E=90=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../haedal/gifticionfunding/exception/CustomException.java | 6 ++++++ .../gifticionfunding/exception/GlobalExceptionHandler.java | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/team/haedal/gifticionfunding/exception/CustomException.java b/src/main/java/team/haedal/gifticionfunding/exception/CustomException.java index 61b5623..c22352b 100644 --- a/src/main/java/team/haedal/gifticionfunding/exception/CustomException.java +++ b/src/main/java/team/haedal/gifticionfunding/exception/CustomException.java @@ -13,4 +13,10 @@ public CustomException(ErrorCode errorCode) { this.errorCode = errorCode; this.message = errorCode.getMessage(); } + + public CustomException(ErrorCode errorCode, String message) { + this.result = errorCode.getStatus(); + this.errorCode = errorCode; + this.message = message; + } } diff --git a/src/main/java/team/haedal/gifticionfunding/exception/GlobalExceptionHandler.java b/src/main/java/team/haedal/gifticionfunding/exception/GlobalExceptionHandler.java index 49d2d50..13facd7 100644 --- a/src/main/java/team/haedal/gifticionfunding/exception/GlobalExceptionHandler.java +++ b/src/main/java/team/haedal/gifticionfunding/exception/GlobalExceptionHandler.java @@ -10,6 +10,6 @@ public ResponseEntity exceptionHandler(CustomException exception) { // exception.printStackTrace(); return ResponseEntity.status(exception.getErrorCode().getError()) - .body(new ExceptionDto(exception.getErrorCode())); + .body(new ExceptionDto(exception.getErrorCode(), exception.getMessage())); } } From d0e37b10a12e6b450341110b979fc82be2a4ead0 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:55:13 +0900 Subject: [PATCH 10/15] =?UTF-8?q?Refac:=20member=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=9D=B4=EB=A6=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gifticionfunding/controller/FriendController.java | 1 - .../gifticionfunding/repository/MemberRepository.java | 2 +- .../haedal/gifticionfunding/service/FriendService.java | 10 +++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java index 66a6a73..e8719e5 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FriendController.java @@ -33,7 +33,6 @@ public ResponseEntity> getFriends(Authentication au @Operation(summary = "친구 요청 API") public void requestFriend(Authentication authentication, @RequestParam(name="friend") Long id){ - System.out.println(authentication.getDetails().toString()); friendService.requestFriend(authentication.getName(),id); } diff --git a/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java index 21a4847..678cab7 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/MemberRepository.java @@ -10,7 +10,7 @@ public interface MemberRepository extends JpaRepository { Optional findByNickname(String nickname); - default Member getUserByEmail(String name) { + default Member getUserByName(String name) { return this.findByNickname(name).orElseThrow( () -> new CustomException(ErrorCode.USER_NOT_FOUND)); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FriendService.java b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java index a4ff871..837d03c 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FriendService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FriendService.java @@ -29,7 +29,7 @@ public class FriendService { @Transactional(readOnly = true) public PageResponse getFriends(int page, String name){ - Member member = memberRepository.getUserByEmail(name); + Member member = memberRepository.getUserByName(name); Page pageData = friendRepository.findAllByMemberAndStatus(PageRequest.of(page, 10), member, FriendStatus.ACCEPT); return PageResponse.builder() @@ -44,7 +44,7 @@ public PageResponse getFriends(int page, String name){ @Transactional() public void requestFriend(String name, Long friendId){ - Member sender = memberRepository.getUserByEmail(name); + Member sender = memberRepository.getUserByName(name); Member receiver = memberRepository.getUserById(friendId); friendRepository.save(Friendship.request(sender,receiver)); @@ -53,7 +53,7 @@ public void requestFriend(String name, Long friendId){ @Transactional() public void acceptFriend(String name, Long friendId){ - Member receiver = memberRepository.getUserByEmail(name); + Member receiver = memberRepository.getUserByName(name); Member sender = memberRepository.getUserById(friendId); Friendship friendship = friendRepository.findByMemberAndFriend(sender, receiver) .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); @@ -64,7 +64,7 @@ public void acceptFriend(String name, Long friendId){ @Transactional() public void rejectFriend(String name, Long friendId){ - Member receiver = memberRepository.getUserByEmail(name); + Member receiver = memberRepository.getUserByName(name); Friendship friendship = friendRepository.findByMemberAndFriend(friendId, receiver.getId()) .orElseThrow(() -> new CustomException(ErrorCode.USER_NOT_FOUND)); @@ -75,7 +75,7 @@ public void rejectFriend(String name, Long friendId){ @Transactional(readOnly = true) public PageResponse getRequestedFriends(int page, String name){ - Member receiver = memberRepository.getUserByEmail(name); + Member receiver = memberRepository.getUserByName(name); Page pageData = friendRepository.findAllByFriendAndStatus(PageRequest.of(page, 10), receiver, FriendStatus.WAITING); return PageResponse.builder() From 7aa954781a3ff11ca74ff258b55f79fc224706ed Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:56:50 +0900 Subject: [PATCH 11/15] =?UTF-8?q?#3=20Feat:=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EA=B4=80=EB=A0=A8=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/FundingArticle.java | 28 +++++++++++++-- .../domain/FundingGifticon.java | 36 ++++++------------- .../gifticionfunding/domain/Gifticon.java | 6 ++-- 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java index 9e9a851..95608c0 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java @@ -2,36 +2,58 @@ import jakarta.persistence.*; import lombok.Builder; +import lombok.Getter; import lombok.NoArgsConstructor; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity +@Getter @NoArgsConstructor public class FundingArticle { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "funding_id") private Long id; @ManyToOne() @OnDelete(action = OnDeleteAction.CASCADE) private Member member; private LocalDateTime createdAt; - private LocalDateTime endAt; + private LocalDate endAt; private String title; @Column(length = 50000) private String content; + @ManyToMany + @JoinTable(name = "funding_gifticon", + joinColumns = @JoinColumn(name = "funding_id"), + inverseJoinColumns = @JoinColumn(name = "gifticon_id")) + private List gifticonList = new ArrayList<>(); @Builder - private FundingArticle(Long id, Member member, LocalDateTime createdAt, LocalDateTime endAt, String title, String content){ + private FundingArticle(Long id, Member member, LocalDateTime createdAt, LocalDate endAt, String title, String content, List gifticonList){ this.id = id; this.member = member; this.createdAt = createdAt; this.endAt = endAt; this.title = title; this.content = content; + this.gifticonList = gifticonList; } -// public static FundingArticle + + public static FundingArticle of(Member member, LocalDate endAt, String title, String content, List gifticonList){ + return FundingArticle.builder() + .member(member) + .createdAt(LocalDateTime.now()) + .endAt(endAt) + .title(title) + .content(content) + .gifticonList(gifticonList) + .build(); + } } diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java index 98e37c4..efb4a60 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java @@ -6,31 +6,15 @@ import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; -@Entity -@NoArgsConstructor -public class FundingGifticon { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - @ManyToOne() - @OnDelete(action = OnDeleteAction.CASCADE) - private Gifticon gifticon; - @ManyToOne() - @OnDelete(action = OnDeleteAction.CASCADE) - private FundingArticle fundingArticle; - - @Builder - private FundingGifticon(Long id, Gifticon gifticon, FundingArticle fundingArticle){ - this.id = id; - this.fundingArticle = fundingArticle; - this.gifticon = gifticon; - } - - public static FundingGifticon of(Gifticon gifticon, FundingArticle fundingArticle){ - return FundingGifticon.builder() - .gifticon(gifticon) - .fundingArticle(fundingArticle) - .build(); - } +public class FundingGifticon { +// @Id +// @GeneratedValue(strategy = GenerationType.IDENTITY) +// private Long id; +// @ManyToOne() +// @OnDelete(action = OnDeleteAction.CASCADE) +// private Gifticon gifticon; +// @ManyToOne() +// @OnDelete(action = OnDeleteAction.CASCADE) +// private FundingArticle fundingArticle; } diff --git a/src/main/java/team/haedal/gifticionfunding/domain/Gifticon.java b/src/main/java/team/haedal/gifticionfunding/domain/Gifticon.java index 56860a0..a001acd 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/Gifticon.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/Gifticon.java @@ -1,10 +1,7 @@ package team.haedal.gifticionfunding.domain; import jakarta.annotation.Nullable; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -21,6 +18,7 @@ public class Gifticon { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "gifticon_id") private Long id; private int price; private String name; From ccc120880d5cdb446627c39d80bc6b7efeaa5c46 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:57:47 +0900 Subject: [PATCH 12/15] =?UTF-8?q?#3=20Feat:=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EA=B4=80=EB=A0=A8=20=EB=A6=AC?= =?UTF-8?q?=ED=8F=AC=EC=A7=80=ED=86=A0=EB=A6=AC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/FundingArticleRepository.java | 7 +++++++ .../gifticionfunding/repository/GifticonRepository.java | 3 +++ 2 files changed, 10 insertions(+) create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java new file mode 100644 index 0000000..b6fcfd0 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import team.haedal.gifticionfunding.domain.FundingArticle; + +public interface FundingArticleRepository extends JpaRepository { +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/GifticonRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/GifticonRepository.java index 3f2bda3..74aa404 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/GifticonRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/GifticonRepository.java @@ -3,5 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import team.haedal.gifticionfunding.domain.Gifticon; +import java.util.List; + public interface GifticonRepository extends JpaRepository { + List findByIdIn(List id); } From e7f21e74e0464a2e77aaac5b62457d637cfe876a Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:59:27 +0900 Subject: [PATCH 13/15] =?UTF-8?q?#3=20Feat:=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EA=B2=8C=EC=8B=9C=EA=B8=80=20=EC=83=9D=EC=84=B1=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/FundingController.java | 39 +++++++++++- .../dto/request/FundingArticleRequest.java | 21 +++++++ .../dto/response/FundingResponse.java | 40 +++++++++++++ .../service/FundingService.java | 60 +++++++++++++++++++ 4 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/request/FundingArticleRequest.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java create mode 100644 src/main/java/team/haedal/gifticionfunding/service/FundingService.java diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java index f33ae5a..2e7c52a 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java @@ -1,10 +1,18 @@ package team.haedal.gifticionfunding.controller; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.data.domain.Page; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import team.haedal.gifticionfunding.dto.PageResponse; +import team.haedal.gifticionfunding.dto.request.FundingArticleRequest; +import team.haedal.gifticionfunding.dto.response.FundingResponse; +import team.haedal.gifticionfunding.service.FundingService; @RestController @RequiredArgsConstructor @@ -14,4 +22,31 @@ public class FundingController { //TODO: 가능한 펀딩 조회, 참여한 펀딩 조회, 생성한 펀딩 조회 //TODO: 펀딩 생성 (유효하지 않은 기프티콘이 하나라도 포함된다면 전체 fail) + private final FundingService fundingService; + + @GetMapping() + @Operation(summary = "가능한 펀딩 조회 API") + public ResponseEntity> getFundings(Authentication authentication){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getFundings(authentication.getName())); + } + + @GetMapping("/participate") + @Operation(summary = "참여한 펀딩 조회 API") + public ResponseEntity> getTakenFundings(Authentication authentication){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getTakenFundings(authentication.getName())); + } + + @GetMapping("/create") + @Operation(summary = "생성한 펀딩 조회 API") + public ResponseEntity> getCreatedFundgins(Authentication authentication){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getCreatedFundgins(authentication.getName())); + } + + @PostMapping("/create") + @Operation(summary = "펀딩 생성 API") + public void createFunding(Authentication authentication, + @RequestBody FundingArticleRequest request){ + fundingService.createFunding(authentication.getName(), request); + } + } diff --git a/src/main/java/team/haedal/gifticionfunding/dto/request/FundingArticleRequest.java b/src/main/java/team/haedal/gifticionfunding/dto/request/FundingArticleRequest.java new file mode 100644 index 0000000..30dfa42 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/request/FundingArticleRequest.java @@ -0,0 +1,21 @@ +package team.haedal.gifticionfunding.dto.request; + +import lombok.Getter; + +import java.time.LocalDate; +import java.util.List; + +@Getter +public class FundingArticleRequest { + /** + * - 사용자는 펀딩을 생성할 수 있다. + * - 펀딩 게시글 생성시 제목, 내용이 포함된다. + * - 펀딩 시 2가지 금액대의 물건을 등록할 수 있다. + * - 2가지 금액대가 아니라 여러개 등록 가능하게 + * - 생일 14일전~ 당일 까지 펀딩 기간을 설정할 수 있다. + */ + private String title; + private String content; + private LocalDate endAt; + private List gifticonIdList; +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java new file mode 100644 index 0000000..d98a6c8 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java @@ -0,0 +1,40 @@ +package team.haedal.gifticionfunding.dto.response; + +import lombok.Builder; +import team.haedal.gifticionfunding.domain.FundingArticle; +import team.haedal.gifticionfunding.domain.Gifticon; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +public class FundingResponse { + private Long id; + private String title; + private String content; + private LocalDateTime createAt; + private LocalDate endAt; + private List gifticonList; + + @Builder + private FundingResponse(Long id, String title, String content, LocalDateTime createAt, LocalDate endAt, List gifticonList){ + this.id = id; + this.title = title; + this.content = content; + this.createAt = createAt; + this.endAt = endAt; + this.gifticonList = gifticonList; + } + + public static FundingResponse of(FundingArticle article, List gifticonList){ + return FundingResponse.builder() + .id(article.getId()) + .title(article.getTitle()) + .content(article.getContent()) + .createAt(article.getCreatedAt()) + .endAt(article.getEndAt()) + .gifticonList(gifticonList) + .build(); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java new file mode 100644 index 0000000..e1f388d --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java @@ -0,0 +1,60 @@ +package team.haedal.gifticionfunding.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import team.haedal.gifticionfunding.common.DateUtils; +import team.haedal.gifticionfunding.domain.FundingArticle; +import team.haedal.gifticionfunding.domain.Gifticon; +import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.dto.PageResponse; +import team.haedal.gifticionfunding.dto.request.FundingArticleRequest; +import team.haedal.gifticionfunding.dto.response.FundingResponse; +import team.haedal.gifticionfunding.exception.CustomException; +import team.haedal.gifticionfunding.exception.ErrorCode; +import team.haedal.gifticionfunding.repository.FundingArticleRepository; +import team.haedal.gifticionfunding.repository.GifticonRepository; +import team.haedal.gifticionfunding.repository.MemberRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class FundingService { + private final MemberRepository memberRepository; + private final FundingArticleRepository fundingArticleRepository; + private final GifticonRepository gifticonRepository; + + public PageResponse getFundings(String name){ + return null; + } + + public PageResponse getTakenFundings(String name){ + return null; + } + + public PageResponse getCreatedFundgins(String name){ + return null; + } + + /** + * 1. member + * 2. 마감일이 유효한지 + * 3. 기프티콘이 유효한지(재고가 남아있어야 함) + */ + public void createFunding(String name, FundingArticleRequest request){ + Member member = memberRepository.getUserByName(name); + + int betweenDate = DateUtils.minus(request.getEndAt(),member.getBirthdate()); + if (betweenDate > 14 || betweenDate < 0) + throw new CustomException(ErrorCode.INVALID_INPUT, "잘못된 마감일입니다."); + + List gifticonList = gifticonRepository.findByIdIn(request.getGifticonIdList()); + gifticonList.forEach(gifticon -> { + if (gifticon.getStock() <= 0) + throw new CustomException(ErrorCode.INVALID_INPUT, "유효하지 않은 기프티콘이 있습니다."); + }); + fundingArticleRepository.save(FundingArticle.of(member, request.getEndAt().plusDays(1), + request.getTitle(), request.getContent(), + gifticonList)); + } +} From faf9cc9563e532b2c4b3fc4cf62f7d2448378a38 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Fri, 10 May 2024 02:59:55 +0900 Subject: [PATCH 14/15] =?UTF-8?q?3=20Feat:=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EA=B0=80=EB=8A=A5=ED=95=9C=20=ED=8E=80=EB=94=A9=EA=B2=8C?= =?UTF-8?q?=EC=8B=9C=EA=B8=80=20=EC=A1=B0=ED=9A=8C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 친구, 친구의 친구까지 조회가능하도록 함 - 펀딩게시글 생성시 마감일 비교 함수 수정 --- .../gifticionfunding/common/DateUtils.java | 20 ++++++ .../controller/FundingController.java | 18 +++-- .../gifticionfunding/domain/Friendship.java | 4 +- .../domain/FundingArticle.java | 10 ++- .../dto/response/FundingResponse.java | 14 ++-- .../dto/response/friend/FriendResponse.java | 1 - .../repository/FundingArticleRepository.java | 16 +++++ .../service/FundingService.java | 39 +++++++++-- .../controller/FriendControllerTest.java | 67 +++++++++++++++++++ 9 files changed, 164 insertions(+), 25 deletions(-) create mode 100644 src/main/java/team/haedal/gifticionfunding/common/DateUtils.java create mode 100644 src/test/java/team/haedal/gifticionfunding/controller/FriendControllerTest.java diff --git a/src/main/java/team/haedal/gifticionfunding/common/DateUtils.java b/src/main/java/team/haedal/gifticionfunding/common/DateUtils.java new file mode 100644 index 0000000..8d2b968 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/common/DateUtils.java @@ -0,0 +1,20 @@ +package team.haedal.gifticionfunding.common; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; + +public final class DateUtils{ + public static String dateToString(LocalDateTime localDateTime) { + return localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); + } + + + public static long diff(LocalDate start, LocalDate end){ + return ChronoUnit.DAYS.between( + LocalDate.of(1, start.getMonth(), start.getDayOfMonth()), + LocalDate.of(1, end.getMonth(), end.getDayOfMonth())); + } + +} diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java index 2e7c52a..9fbf05c 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java @@ -1,9 +1,9 @@ package team.haedal.gifticionfunding.controller; +import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; @@ -26,20 +26,24 @@ public class FundingController { @GetMapping() @Operation(summary = "가능한 펀딩 조회 API") - public ResponseEntity> getFundings(Authentication authentication){ - return ResponseEntity.status(HttpStatus.OK).body(fundingService.getFundings(authentication.getName())); + public ResponseEntity> getFundings(Authentication authentication, + @RequestParam(value="page", defaultValue="0") int page){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getFundings(page, authentication.getName())); } @GetMapping("/participate") @Operation(summary = "참여한 펀딩 조회 API") - public ResponseEntity> getTakenFundings(Authentication authentication){ - return ResponseEntity.status(HttpStatus.OK).body(fundingService.getTakenFundings(authentication.getName())); + @Hidden + public ResponseEntity> getTakenFundings(Authentication authentication, + @RequestParam(value="page", defaultValue="0") int page){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getTakenFundings(page, authentication.getName())); } @GetMapping("/create") @Operation(summary = "생성한 펀딩 조회 API") - public ResponseEntity> getCreatedFundgins(Authentication authentication){ - return ResponseEntity.status(HttpStatus.OK).body(fundingService.getCreatedFundgins(authentication.getName())); + public ResponseEntity> getCreatedFundgins(Authentication authentication, + @RequestParam(value="page", defaultValue="0") int page){ + return ResponseEntity.status(HttpStatus.OK).body(fundingService.getCreatedFundgins(page, authentication.getName())); } @PostMapping("/create") diff --git a/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java index 3ae148b..1c32da5 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/Friendship.java @@ -18,11 +18,11 @@ public class Friendship { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne() + @ManyToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private Member member; - @ManyToOne() + @ManyToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private Member friend; diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java index 95608c0..8c074dc 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java @@ -20,15 +20,21 @@ public class FundingArticle { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "funding_id") private Long id; - @ManyToOne() + + @ManyToOne(fetch = FetchType.LAZY) @OnDelete(action = OnDeleteAction.CASCADE) private Member member; + private LocalDateTime createdAt; + private LocalDate endAt; + private String title; + @Column(length = 50000) private String content; - @ManyToMany + + @ManyToMany(fetch = FetchType.LAZY) @JoinTable(name = "funding_gifticon", joinColumns = @JoinColumn(name = "funding_id"), inverseJoinColumns = @JoinColumn(name = "gifticon_id")) diff --git a/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java index d98a6c8..3af86f6 100644 --- a/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java +++ b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java @@ -1,6 +1,7 @@ package team.haedal.gifticionfunding.dto.response; import lombok.Builder; +import lombok.Getter; import team.haedal.gifticionfunding.domain.FundingArticle; import team.haedal.gifticionfunding.domain.Gifticon; @@ -8,12 +9,13 @@ import java.time.LocalDateTime; import java.util.List; +@Getter public class FundingResponse { private Long id; private String title; private String content; - private LocalDateTime createAt; - private LocalDate endAt; + private String createAt; + private String endAt; private List gifticonList; @Builder @@ -21,19 +23,19 @@ private FundingResponse(Long id, String title, String content, LocalDateTime cre this.id = id; this.title = title; this.content = content; - this.createAt = createAt; - this.endAt = endAt; + this.createAt = createAt.toString(); + this.endAt = endAt.toString(); this.gifticonList = gifticonList; } - public static FundingResponse of(FundingArticle article, List gifticonList){ + public static FundingResponse from(FundingArticle article){ return FundingResponse.builder() .id(article.getId()) .title(article.getTitle()) .content(article.getContent()) .createAt(article.getCreatedAt()) .endAt(article.getEndAt()) - .gifticonList(gifticonList) + .gifticonList(article.getGifticonList()) .build(); } diff --git a/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java index 11c9567..b8c8cbb 100644 --- a/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java +++ b/src/main/java/team/haedal/gifticionfunding/dto/response/friend/FriendResponse.java @@ -7,7 +7,6 @@ import java.time.LocalDate; -@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) @Getter public class FriendResponse { private Long id; diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java index b6fcfd0..9fb3cb9 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java @@ -1,7 +1,23 @@ package team.haedal.gifticionfunding.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import team.haedal.gifticionfunding.domain.FundingArticle; +import team.haedal.gifticionfunding.domain.Member; public interface FundingArticleRepository extends JpaRepository { + Page findByMember(Pageable pageable, Member member); + + @Query(value = "select * from funding_article where member_id in " + + "((select distinct b.friend_id " + + "from friendship a join friendship b " + + "where a.member_id = :memberId and b.friend_id != :memberId " + + "and a.friend_id=b.member_id) " + + "union " + + "(select a.friend_id " + + "from friendship a where a.member_id = :memberId))",nativeQuery = true) + Page findByFriendAndFriendOfFriend(Pageable pageable, @Param("memberId") Long memberId); } diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java index e1f388d..0fb625d 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java @@ -1,8 +1,9 @@ package team.haedal.gifticionfunding.service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; -import team.haedal.gifticionfunding.common.DateUtils; import team.haedal.gifticionfunding.domain.FundingArticle; import team.haedal.gifticionfunding.domain.Gifticon; import team.haedal.gifticionfunding.domain.Member; @@ -16,6 +17,9 @@ import team.haedal.gifticionfunding.repository.MemberRepository; import java.util.List; +import java.util.stream.Collectors; + +import static team.haedal.gifticionfunding.common.DateUtils.diff; @Service @RequiredArgsConstructor @@ -24,16 +28,37 @@ public class FundingService { private final FundingArticleRepository fundingArticleRepository; private final GifticonRepository gifticonRepository; - public PageResponse getFundings(String name){ - return null; + public PageResponse getFundings(int page, String name){ + /** + * funding article 의 작성자가 친구인 경우, 친구의 친구인 경우 조회 + */ + Member owner = memberRepository.getUserByName(name); + Page pageData = fundingArticleRepository.findByFriendAndFriendOfFriend(PageRequest.of(page, 10), owner.getId()); + + return PageResponse.builder() + .content(pageData.getContent().stream() + .map(FundingResponse::from) + .collect(Collectors.toList())) + .page(pageData.getNumber()) + .isLast(pageData.isLast()) + .build(); } - public PageResponse getTakenFundings(String name){ + public PageResponse getTakenFundings(int page, String name){ return null; } - public PageResponse getCreatedFundgins(String name){ - return null; + public PageResponse getCreatedFundgins(int page, String name){ + Member owner = memberRepository.getUserByName(name); + Page pageData = fundingArticleRepository.findByMember(PageRequest.of(page, 10), owner); + + return PageResponse.builder() + .content(pageData.getContent().stream() + .map(FundingResponse::from) + .collect(Collectors.toList())) + .page(pageData.getNumber()) + .isLast(pageData.isLast()) + .build(); } /** @@ -44,7 +69,7 @@ public PageResponse getCreatedFundgins(String name){ public void createFunding(String name, FundingArticleRequest request){ Member member = memberRepository.getUserByName(name); - int betweenDate = DateUtils.minus(request.getEndAt(),member.getBirthdate()); + long betweenDate = diff(request.getEndAt(),member.getBirthdate()); if (betweenDate > 14 || betweenDate < 0) throw new CustomException(ErrorCode.INVALID_INPUT, "잘못된 마감일입니다."); diff --git a/src/test/java/team/haedal/gifticionfunding/controller/FriendControllerTest.java b/src/test/java/team/haedal/gifticionfunding/controller/FriendControllerTest.java new file mode 100644 index 0000000..4702b62 --- /dev/null +++ b/src/test/java/team/haedal/gifticionfunding/controller/FriendControllerTest.java @@ -0,0 +1,67 @@ +package team.haedal.gifticionfunding.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import team.haedal.gifticionfunding.dto.response.GifticonResponse; +import team.haedal.gifticionfunding.service.FriendService; +import team.haedal.gifticionfunding.service.GifticonServiceImpl; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.BDDMockito.given; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@WebMvcTest(FriendController.class) +@AutoConfigureMockMvc +class FriendControllerTest { + @Autowired + private MockMvc mockMvc; + + @MockBean + FriendService friendService; + + @Autowired + ObjectMapper objectMapper; + + //TODO: Test: 승인된 친구만 조회되는지(승인된 친구가 요청목록에 없어지는지), 친구 중복 요청안되는지 + //TODO: Test: 만약에 두명이 서로 친구 요청을 보내고 하나의 요청이 승인되면 -> 둘은 친구임 -> 근데 waiting인게 디비에 영원히 남아있음 + //TODO: Test: 친구가 서로 동시에 요청을 보낸다면? + + @Test + @DisplayName("친구목록 조회 테스트") + void getFriends() { + + } + + @Test + @DisplayName("친구 요청 테스트") + void requestFriend() { + } + + @Test + @DisplayName("친구 수락 테스트") + void acceptFriend() { + } + + @Test + @DisplayName("친구 거절 테스트") + void rejectFriend() { + } + + @Test + @DisplayName("요청된 친구 목록 조회 테스트") + void getRequestedFriends() { + } +} \ No newline at end of file From 1fb854c8cc056aa601904094a430110653c23fc4 Mon Sep 17 00:00:00 2001 From: kwonssshyeon Date: Sat, 25 May 2024 20:33:28 +0900 Subject: [PATCH 15/15] =?UTF-8?q?#3=20Feat:=20=ED=8E=80=EB=94=A9=20?= =?UTF-8?q?=EC=B0=B8=EC=97=AC=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- .../controller/FundingController.java | 12 +- .../domain/FundingGifticon.java | 20 --- .../domain/{ => funding}/FundingArticle.java | 4 +- .../domain/funding/FundingContribute.java | 58 +++++++++ .../domain/funding/FundingGifticon.java | 40 ++++++ .../dto/request/FundingJoinRequest.java | 9 ++ .../dto/response/FundingResponse.java | 2 +- .../repository/FriendRepository.java | 2 +- .../repository/FundingArticleRepository.java | 2 +- .../FundingContributeRepository.java | 7 + .../repository/FundingGifticonRepository.java | 7 + .../repository/MemberGifticonRepository.java | 7 + .../service/FundingService.java | 39 +++++- .../controller/GifticonControllerTest.java | 5 +- .../service/FriendServiceTest.java | 123 ++++++++++++++++++ 16 files changed, 305 insertions(+), 34 deletions(-) delete mode 100644 src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java rename src/main/java/team/haedal/gifticionfunding/domain/{ => funding}/FundingArticle.java (92%) create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/funding/FundingContribute.java create mode 100644 src/main/java/team/haedal/gifticionfunding/domain/funding/FundingGifticon.java create mode 100644 src/main/java/team/haedal/gifticionfunding/dto/request/FundingJoinRequest.java create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/FundingContributeRepository.java create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/FundingGifticonRepository.java create mode 100644 src/main/java/team/haedal/gifticionfunding/repository/MemberGifticonRepository.java create mode 100644 src/test/java/team/haedal/gifticionfunding/service/FriendServiceTest.java diff --git a/.gitignore b/.gitignore index 1bd5099..853ec00 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,4 @@ out/ .vscode/ src/main/resources/application.yml src/main/java/team/haedal/gifticionfunding/service/OAuth2SuccessHandler.java -src/main/resources/data.sql \ No newline at end of file +src/main/resources/dataSample.sql \ No newline at end of file diff --git a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java index 9fbf05c..3dccf08 100644 --- a/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java +++ b/src/main/java/team/haedal/gifticionfunding/controller/FundingController.java @@ -11,6 +11,7 @@ import org.springframework.web.servlet.config.annotation.EnableWebMvc; import team.haedal.gifticionfunding.dto.PageResponse; import team.haedal.gifticionfunding.dto.request.FundingArticleRequest; +import team.haedal.gifticionfunding.dto.request.FundingJoinRequest; import team.haedal.gifticionfunding.dto.response.FundingResponse; import team.haedal.gifticionfunding.service.FundingService; @@ -39,18 +40,25 @@ public ResponseEntity> getTakenFundings(Authentica return ResponseEntity.status(HttpStatus.OK).body(fundingService.getTakenFundings(page, authentication.getName())); } - @GetMapping("/create") + @GetMapping("/created") @Operation(summary = "생성한 펀딩 조회 API") public ResponseEntity> getCreatedFundgins(Authentication authentication, @RequestParam(value="page", defaultValue="0") int page){ return ResponseEntity.status(HttpStatus.OK).body(fundingService.getCreatedFundgins(page, authentication.getName())); } - @PostMapping("/create") + @PostMapping() @Operation(summary = "펀딩 생성 API") public void createFunding(Authentication authentication, @RequestBody FundingArticleRequest request){ fundingService.createFunding(authentication.getName(), request); } + @PostMapping("/participate") + @Operation(summary = "펀딩 참여 API") + public void participateFunding(Authentication authentication, + @RequestBody FundingJoinRequest request){ + fundingService.participateFunding(authentication.getName(), request); + } + } diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java b/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java deleted file mode 100644 index efb4a60..0000000 --- a/src/main/java/team/haedal/gifticionfunding/domain/FundingGifticon.java +++ /dev/null @@ -1,20 +0,0 @@ -package team.haedal.gifticionfunding.domain; - -import jakarta.persistence.*; -import lombok.Builder; -import lombok.NoArgsConstructor; -import org.hibernate.annotations.OnDelete; -import org.hibernate.annotations.OnDeleteAction; - - -public class FundingGifticon { -// @Id -// @GeneratedValue(strategy = GenerationType.IDENTITY) -// private Long id; -// @ManyToOne() -// @OnDelete(action = OnDeleteAction.CASCADE) -// private Gifticon gifticon; -// @ManyToOne() -// @OnDelete(action = OnDeleteAction.CASCADE) -// private FundingArticle fundingArticle; -} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingArticle.java similarity index 92% rename from src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java rename to src/main/java/team/haedal/gifticionfunding/domain/funding/FundingArticle.java index 8c074dc..da9149a 100644 --- a/src/main/java/team/haedal/gifticionfunding/domain/FundingArticle.java +++ b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingArticle.java @@ -1,4 +1,4 @@ -package team.haedal.gifticionfunding.domain; +package team.haedal.gifticionfunding.domain.funding; import jakarta.persistence.*; import lombok.Builder; @@ -6,6 +6,8 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDeleteAction; +import team.haedal.gifticionfunding.domain.Gifticon; +import team.haedal.gifticionfunding.domain.Member; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingContribute.java b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingContribute.java new file mode 100644 index 0000000..bab57a2 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingContribute.java @@ -0,0 +1,58 @@ +package team.haedal.gifticionfunding.domain.funding; + +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; +import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.domain.MemberGifticon; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor +public class FundingContribute { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @OnDelete(action = OnDeleteAction.CASCADE) + private Member participant; + + @ManyToOne(fetch = FetchType.LAZY) + @OnDelete(action = OnDeleteAction.CASCADE) + private FundingArticle fundingArticle; + + @ManyToOne(fetch = FetchType.LAZY) + @OnDelete(action = OnDeleteAction.CASCADE) + private MemberGifticon memberGifticon; + + private LocalDateTime createdAt; + + private int point; + + @Builder + private FundingContribute(Member participant, FundingArticle fundingArticle, MemberGifticon memberGifticon, LocalDateTime createdAt, int point){ + this.participant = participant; + this.fundingArticle = fundingArticle; + this.memberGifticon = memberGifticon; + this.createdAt = createdAt; + this.point = point; + } + + public static FundingContribute of(Member participant, FundingArticle fundingArticle, MemberGifticon memberGifticon, int point){ + return FundingContribute.builder() + .participant(participant) + .fundingArticle(fundingArticle) + .memberGifticon(memberGifticon) + .createdAt(LocalDateTime.now()) + .point(point) + .build(); + } + + +} diff --git a/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingGifticon.java b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingGifticon.java new file mode 100644 index 0000000..1b71493 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/domain/funding/FundingGifticon.java @@ -0,0 +1,40 @@ +package team.haedal.gifticionfunding.domain.funding; + +import jakarta.persistence.*; +import lombok.Builder; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; +import team.haedal.gifticionfunding.domain.Gifticon; + + +@Entity +@NoArgsConstructor +public class FundingGifticon { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + @ManyToOne() + @JoinColumn(name = "gifticon_id") + @OnDelete(action = OnDeleteAction.CASCADE) + private Gifticon gifticon; + @ManyToOne() + @OnDelete(action = OnDeleteAction.CASCADE) + @JoinColumn(name = "funding_article_id") + private FundingArticle fundingArticle; + private int point; + + @Builder + private FundingGifticon(FundingArticle fundingArticle, Gifticon gifticon) { + this.fundingArticle = fundingArticle; + this.gifticon = gifticon; + this.point = gifticon.getPrice(); + } + + public static FundingGifticon create(FundingArticle fundingArticle, Gifticon gifticon) { + return FundingGifticon.builder() + .fundingArticle(fundingArticle) + .gifticon(gifticon) + .build(); + } +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/request/FundingJoinRequest.java b/src/main/java/team/haedal/gifticionfunding/dto/request/FundingJoinRequest.java new file mode 100644 index 0000000..c6d5626 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/dto/request/FundingJoinRequest.java @@ -0,0 +1,9 @@ +package team.haedal.gifticionfunding.dto.request; + +import lombok.Getter; + +@Getter +public class FundingJoinRequest { + private Long articleId; + private Long memberGifticonId; +} diff --git a/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java index 3af86f6..a2c84b9 100644 --- a/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java +++ b/src/main/java/team/haedal/gifticionfunding/dto/response/FundingResponse.java @@ -2,7 +2,7 @@ import lombok.Builder; import lombok.Getter; -import team.haedal.gifticionfunding.domain.FundingArticle; +import team.haedal.gifticionfunding.domain.funding.FundingArticle; import team.haedal.gifticionfunding.domain.Gifticon; import java.time.LocalDate; diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java index a4ae275..16f07bc 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/FriendRepository.java @@ -5,6 +5,7 @@ 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 team.haedal.gifticionfunding.domain.Friendship; import team.haedal.gifticionfunding.domain.Member; import team.haedal.gifticionfunding.domain.enums.FriendStatus; @@ -12,7 +13,6 @@ import team.haedal.gifticionfunding.repository.vo.MemberOnly; import java.util.Optional; - public interface FriendRepository extends JpaRepository { Page findAllByMemberAndStatus(Pageable pageable, Member member, FriendStatus status); Page findAllByFriendAndStatus(Pageable pageable, Member friend, FriendStatus status); diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java index 9fb3cb9..8896c68 100644 --- a/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java +++ b/src/main/java/team/haedal/gifticionfunding/repository/FundingArticleRepository.java @@ -5,7 +5,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; -import team.haedal.gifticionfunding.domain.FundingArticle; +import team.haedal.gifticionfunding.domain.funding.FundingArticle; import team.haedal.gifticionfunding.domain.Member; public interface FundingArticleRepository extends JpaRepository { diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FundingContributeRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FundingContributeRepository.java new file mode 100644 index 0000000..a25403a --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/FundingContributeRepository.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import team.haedal.gifticionfunding.domain.funding.FundingContribute; + +public interface FundingContributeRepository extends JpaRepository { +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/FundingGifticonRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/FundingGifticonRepository.java new file mode 100644 index 0000000..4badbd4 --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/FundingGifticonRepository.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import team.haedal.gifticionfunding.domain.funding.FundingGifticon; + +public interface FundingGifticonRepository extends JpaRepository { +} diff --git a/src/main/java/team/haedal/gifticionfunding/repository/MemberGifticonRepository.java b/src/main/java/team/haedal/gifticionfunding/repository/MemberGifticonRepository.java new file mode 100644 index 0000000..c2c5f6d --- /dev/null +++ b/src/main/java/team/haedal/gifticionfunding/repository/MemberGifticonRepository.java @@ -0,0 +1,7 @@ +package team.haedal.gifticionfunding.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import team.haedal.gifticionfunding.domain.MemberGifticon; + +public interface MemberGifticonRepository extends JpaRepository { +} diff --git a/src/main/java/team/haedal/gifticionfunding/service/FundingService.java b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java index 0fb625d..a515bfd 100644 --- a/src/main/java/team/haedal/gifticionfunding/service/FundingService.java +++ b/src/main/java/team/haedal/gifticionfunding/service/FundingService.java @@ -4,17 +4,16 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; -import team.haedal.gifticionfunding.domain.FundingArticle; -import team.haedal.gifticionfunding.domain.Gifticon; -import team.haedal.gifticionfunding.domain.Member; +import org.springframework.transaction.annotation.Transactional; +import team.haedal.gifticionfunding.domain.*; +import team.haedal.gifticionfunding.domain.funding.FundingArticle; import team.haedal.gifticionfunding.dto.PageResponse; import team.haedal.gifticionfunding.dto.request.FundingArticleRequest; +import team.haedal.gifticionfunding.dto.request.FundingJoinRequest; import team.haedal.gifticionfunding.dto.response.FundingResponse; import team.haedal.gifticionfunding.exception.CustomException; import team.haedal.gifticionfunding.exception.ErrorCode; -import team.haedal.gifticionfunding.repository.FundingArticleRepository; -import team.haedal.gifticionfunding.repository.GifticonRepository; -import team.haedal.gifticionfunding.repository.MemberRepository; +import team.haedal.gifticionfunding.repository.*; import java.util.List; import java.util.stream.Collectors; @@ -27,7 +26,11 @@ public class FundingService { private final MemberRepository memberRepository; private final FundingArticleRepository fundingArticleRepository; private final GifticonRepository gifticonRepository; + private final FundingContributeRepository contributeRepository; + private final MemberGifticonRepository memberGifticonRepository; + private final FundingGifticonRepository fundingGifticonRepository; + @Transactional(readOnly = true) public PageResponse getFundings(int page, String name){ /** * funding article 의 작성자가 친구인 경우, 친구의 친구인 경우 조회 @@ -44,6 +47,7 @@ public PageResponse getFundings(int page, String name){ .build(); } + @Transactional(readOnly = true) public PageResponse getTakenFundings(int page, String name){ return null; } @@ -66,6 +70,7 @@ public PageResponse getCreatedFundgins(int page, String name){ * 2. 마감일이 유효한지 * 3. 기프티콘이 유효한지(재고가 남아있어야 함) */ + @Transactional public void createFunding(String name, FundingArticleRequest request){ Member member = memberRepository.getUserByName(name); @@ -82,4 +87,26 @@ public void createFunding(String name, FundingArticleRequest request){ request.getTitle(), request.getContent(), gifticonList)); } + + + /** + * 게시자의 친구의 친구는 펀딩에 참여할 수 있다. + * 선택한 기프티콘이 게시자가 게시한 기프티콘 목록에 있다면 contribute를 한다. + * @param name + * @param request + */ + @Transactional + public void participateFunding(String name, FundingJoinRequest request){ + Member member = memberRepository.getUserByName(name); + FundingArticle fundingArticle = fundingArticleRepository.findById(request.getArticleId()) + .orElseThrow(() -> new CustomException(ErrorCode.INVALID_INPUT, "존재하지 않는 게시글입니다.")); + MemberGifticon gifticon = memberGifticonRepository.findById(request.getMemberGifticonId()) + .orElseThrow(() -> new CustomException(ErrorCode.INVALID_INPUT, "존재하지 않는 기프티콘입니다.")); + + if (!fundingArticle.getGifticonList().contains(request.getMemberGifticonId())){ + throw new CustomException(ErrorCode.INVALID_INPUT,"존재하지 않는 기프티콘입니다."); + } + + + } } diff --git a/src/test/java/team/haedal/gifticionfunding/controller/GifticonControllerTest.java b/src/test/java/team/haedal/gifticionfunding/controller/GifticonControllerTest.java index 99dd5ed..a719f93 100644 --- a/src/test/java/team/haedal/gifticionfunding/controller/GifticonControllerTest.java +++ b/src/test/java/team/haedal/gifticionfunding/controller/GifticonControllerTest.java @@ -19,13 +19,13 @@ import java.util.List; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.verify; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.oauth2Login; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @WebMvcTest(GifticonController.class) -@AutoConfigureMockMvc public class GifticonControllerTest { @Autowired private MockMvc mockMvc; @@ -82,5 +82,8 @@ void getGifticonDetail() throws Exception { .andExpect(jsonPath("$.expirationDate").exists()) .andDo(print()); + // verify : 메소드가 실행이 됐는지를 확인 + verify(gifticonService).getGifticonDetail(1L); + } } diff --git a/src/test/java/team/haedal/gifticionfunding/service/FriendServiceTest.java b/src/test/java/team/haedal/gifticionfunding/service/FriendServiceTest.java new file mode 100644 index 0000000..cdd101d --- /dev/null +++ b/src/test/java/team/haedal/gifticionfunding/service/FriendServiceTest.java @@ -0,0 +1,123 @@ +package team.haedal.gifticionfunding.service; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.springframework.test.context.junit.jupiter.SpringExtension; +import team.haedal.gifticionfunding.domain.Friendship; +import team.haedal.gifticionfunding.domain.Member; +import team.haedal.gifticionfunding.domain.enums.FriendStatus; +import team.haedal.gifticionfunding.domain.enums.Role; +import team.haedal.gifticionfunding.repository.FriendRepository; +import team.haedal.gifticionfunding.repository.MemberRepository; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.Optional; + + +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.verify; + +@ExtendWith(SpringExtension.class) +public class FriendServiceTest { + @Mock + private MemberRepository memberRepository; + @Mock + private FriendRepository friendRepository; + @InjectMocks + private FriendService friendService; + + @Override + public boolean equals(Object o){ + Friendship friendship = (Friendship) o; + return true; + } + + + + //TODO: Test: 승인된 친구만 조회되는지(승인된 친구가 요청목록에 없어지는지), 친구 중복 요청안되는지 + //TODO: Test: 만약에 두명이 서로 친구 요청을 보내고 하나의 요청이 승인되면 -> 둘은 친구임 -> 근데 waiting인게 디비에 영원히 남아있음 + //TODO: Test: 친구가 서로 동시에 요청을 보낸다면? + + @Test + void requestFriend() { + String[] attrs = toArray("좋은","빠른"); + } + + static T[] pickTwo(T a, T b) { + System.out.println("pickTwo: "+a.getClass()); + return toArray(a, b); + } + static T[] toArray(T... args){ + System.out.println("toArray: "+args.getClass()); + return args; + } + + + + @Test + void getRequestedFriends() { + //given + Member member = createMember("사용자"); + Member friend1 = createMember("친구"); + Mockito.when(memberRepository.getUserByName(member.getNickname())).thenReturn(member); + Mockito.when(memberRepository.findById(friend1.getId())).thenReturn(Optional.of(friend1)); + + //given + Friendship friendship = createFriendRequest(friend1,member); + + friendService.requestFriend(member.getNickname(),friend1.getId()); + + verify(friendRepository).save(any(Friendship.class)); + } + + @Test + void acceptFriend() { + } + + @Test + @DisplayName("사용자와 친구관계인 member를 조회한다.") + void getFriends() { + //given + + + + + //when + + } + + + @Test + void rejectFriend() { + } + + + Member createMember(String name){ + return Member.builder() + .email("email@email.com") + .nickname(name) + .point(0L) + .birthdate(LocalDate.of(2001,9,15)) + .profileImageUrl("http://profile.png") + .role(Role.MEMBER) + .build(); + } + + Friendship createFriendRequest(Member to, Member from){ + return Friendship.builder() + .createdAt(LocalDateTime.now()) + .member(from) + .friend(to) + .status(FriendStatus.WAITING) + .build(); + } + + + + +}