From 031bd9fc50d7233f5161c04c33bf3dd70544200b Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Mon, 5 Aug 2024 21:31:23 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=EC=95=8C=EB=A6=BC=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=EC=97=90=20=EC=8A=A4=EC=9B=A8?= =?UTF-8?q?=EA=B1=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/NotificationController.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java index 186b024c..c877408e 100644 --- a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java @@ -9,8 +9,12 @@ import com.umc.naoman.global.result.ResultResponse; import com.umc.naoman.global.result.code.NotificationResultCode; import com.umc.naoman.global.security.annotation.LoginMember; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -24,10 +28,20 @@ @RestController @RequiredArgsConstructor @RequestMapping("/notifications") +@Tag(name = "알림 관련 API", description = " 알림 전체 목록 조희, fcm 토큰 업로드, 알림 1개 삭제, 알림 전체 삭제, 읽지 않은 알림 유무, 내 알람 전체 읽음 처리를 하는 API입니다.") public class NotificationController { private final NotificationService notificationService; @PostMapping("/token") + @Operation( + summary = "fcm 토큰 업로드", + description = "안드로이드가 fcm 토큰을 서버에 업로드하는 API입니다.", + requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody( + content = @Content( + schema = @Schema(implementation = NotificationRequest.FcmToken.class) + ) + ) + ) public ResultResponse registerFcmToken(@RequestBody NotificationRequest.FcmToken fcmToken, @LoginMember Member member){ @@ -39,6 +53,7 @@ public ResultResponse registerFcmToken(@RequestBody NotificationRequest.Fc @Parameter(name = "page", description = "조회할 페이지를 입력해 주세요.(0번부터 시작)"), @Parameter(name = "size", description = "한 페이지에 나타낼 알림 개수를 입력해주세요.") }) + @Operation(summary = "자신의 모든 알림 조회", description = "자신의 모든 알림을 조회하는 API입니다.") public ResultResponse getNotifications(@LoginMember Member member, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable){ @@ -48,6 +63,9 @@ public ResultResponse getNotificatio } @GetMapping("/unread") + @Operation(summary = "읽지 않은 알림 유무 조회", + description = "읽지 않은 알림 유무 조회하는 API입니다.", + parameters = {}) public ResultResponse getIsUnread(@LoginMember Member member){ List notificationList = notificationService.isUnreadNotification(member); return ResultResponse.of(NotificationResultCode.CHECK_MY_UNREAD_NOTIFICATION, @@ -55,6 +73,9 @@ public ResultResponse getIsUnread(@Logi } @PostMapping("/acknowledgements") + @Operation(summary = "모든 알림 읽음 처리", + description = "자신의 모든 알림을 읽음 처리하는 API입니다.", + parameters = {}) public ResultResponse setMyNotificationRead(@LoginMember Member member){ List notificationList = notificationService.setMyNotificationRead(member); return ResultResponse.of(NotificationResultCode.READ_ALL_MY_NOTIFICATION, @@ -62,6 +83,11 @@ public ResultResponse setMyNo } @DeleteMapping("/{notificationId}") + @Operation(summary = "특정 알림 1개 삭제", + description = "특정 알림 1개를 삭제하는 API입니다.", + parameters = { + @Parameter(name = "notificationId", description = "삭제할 알림의 Id", required = true, schema = @Schema(type = "long")) + }) public ResultResponse deleteNotification(@PathVariable Long notificationId, @LoginMember Member member){ long deletedCount = notificationService.deleteNotification(member,notificationId); @@ -69,6 +95,9 @@ public ResultResponse deleteN NotificationConverter.toNotificationAcknowledgedCount(deletedCount)); } @DeleteMapping + @Operation(summary = "모든 알림 삭제", + description = "자신의 모든 알림을 삭제하는 API입니다.", + parameters = {}) public ResultResponse deleteAllNotification(@LoginMember Member member){ long deletedCount = notificationService.deleteNotificationAll(member); return ResultResponse.of(NotificationResultCode.DELETE_MY_NOTIFICATION, From 88f143fe0c4f2d1874a32d69105be76498155410 Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Mon, 5 Aug 2024 23:16:41 +0900 Subject: [PATCH 02/18] =?UTF-8?q?refact=20:=20=EC=BB=A8=EB=B2=84=ED=84=B0?= =?UTF-8?q?=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A5=BC=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=A1=9C=20=EC=B9=98=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/NotificationController.java | 21 +++++++++++-------- .../converter/NotificationConverter.java | 20 ++++++++++-------- .../dto/NotificationResponse.java | 2 +- .../notification/service/FcmService.java | 4 +++- .../notification/service/FcmServiceImpl.java | 6 +++--- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java index c877408e..442f98f6 100644 --- a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java @@ -5,6 +5,7 @@ import com.umc.naoman.domain.notification.dto.NotificationRequest; import com.umc.naoman.domain.notification.dto.NotificationResponse; import com.umc.naoman.domain.notification.entity.Notification; +import com.umc.naoman.domain.notification.service.FcmService; import com.umc.naoman.domain.notification.service.NotificationService; import com.umc.naoman.global.result.ResultResponse; import com.umc.naoman.global.result.code.NotificationResultCode; @@ -31,6 +32,8 @@ @Tag(name = "알림 관련 API", description = " 알림 전체 목록 조희, fcm 토큰 업로드, 알림 1개 삭제, 알림 전체 삭제, 읽지 않은 알림 유무, 내 알람 전체 읽음 처리를 하는 API입니다.") public class NotificationController { private final NotificationService notificationService; + private final FcmService fcmService; + private final NotificationConverter notificationConverter; @PostMapping("/token") @Operation( @@ -44,7 +47,7 @@ public class NotificationController { ) public ResultResponse registerFcmToken(@RequestBody NotificationRequest.FcmToken fcmToken, @LoginMember Member member){ - + fcmService.saveFcmToken(member, fcmToken.getToken()); return ResultResponse.of(NotificationResultCode.REGISTER_FCM_TOKEN,null); } @@ -59,17 +62,17 @@ public ResultResponse getNotificatio @Parameter(hidden = true) Pageable pageable){ Page notificationPage = notificationService.getNotificationList(member, pageable); return ResultResponse.of(NotificationResultCode.GET_MY_NOTIFICATION, - NotificationConverter.toNotificationInfo(notificationPage)); + notificationConverter.toNotificationInfo(notificationPage)); } @GetMapping("/unread") @Operation(summary = "읽지 않은 알림 유무 조회", description = "읽지 않은 알림 유무 조회하는 API입니다.", parameters = {}) - public ResultResponse getIsUnread(@LoginMember Member member){ + public ResultResponse getIsUnread(@LoginMember Member member){ List notificationList = notificationService.isUnreadNotification(member); return ResultResponse.of(NotificationResultCode.CHECK_MY_UNREAD_NOTIFICATION, - NotificationConverter.toUnreadNotification(notificationList)); + notificationConverter.toIsUnread(notificationList)); } @PostMapping("/acknowledgements") @@ -79,12 +82,12 @@ public ResultResponse getIsUnread(@Logi public ResultResponse setMyNotificationRead(@LoginMember Member member){ List notificationList = notificationService.setMyNotificationRead(member); return ResultResponse.of(NotificationResultCode.READ_ALL_MY_NOTIFICATION, - NotificationConverter.toNotificationAcknowledgedCount(notificationList)); + notificationConverter.toNotificationAcknowledgedCount(notificationList)); } @DeleteMapping("/{notificationId}") - @Operation(summary = "특정 알림 1개 삭제", - description = "특정 알림 1개를 삭제하는 API입니다.", + @Operation(summary = "특정 알림 삭제", + description = "특정 알림을 삭제하는 API입니다.", parameters = { @Parameter(name = "notificationId", description = "삭제할 알림의 Id", required = true, schema = @Schema(type = "long")) }) @@ -92,7 +95,7 @@ public ResultResponse deleteN @LoginMember Member member){ long deletedCount = notificationService.deleteNotification(member,notificationId); return ResultResponse.of(NotificationResultCode.DELETE_MY_NOTIFICATION, - NotificationConverter.toNotificationAcknowledgedCount(deletedCount)); + notificationConverter.toNotificationAcknowledgedCount(deletedCount)); } @DeleteMapping @Operation(summary = "모든 알림 삭제", @@ -101,6 +104,6 @@ public ResultResponse deleteN public ResultResponse deleteAllNotification(@LoginMember Member member){ long deletedCount = notificationService.deleteNotificationAll(member); return ResultResponse.of(NotificationResultCode.DELETE_MY_NOTIFICATION, - NotificationConverter.toNotificationDeletedCount(deletedCount)); + notificationConverter.toNotificationDeletedCount(deletedCount)); } } diff --git a/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java b/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java index 146c5e9d..4b376230 100644 --- a/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java +++ b/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java @@ -6,13 +6,15 @@ import com.umc.naoman.domain.notification.entity.DeviceToken; import com.umc.naoman.domain.notification.entity.Notification; import org.springframework.data.domain.Page; +import org.springframework.stereotype.Component; import java.util.List; import java.util.stream.Collectors; +@Component public class NotificationConverter { - public static NotificationResponse.NotificationInfo notificationInfo(Notification notification){ + public NotificationResponse.NotificationInfo notificationInfo(Notification notification){ return NotificationResponse.NotificationInfo.builder() .body(notification.getMessage()) .createdAt(notification.getCreatedAt()) @@ -20,10 +22,10 @@ public static NotificationResponse.NotificationInfo notificationInfo(Notificatio .url(notification.makeNotificationInfoURL()) //다형성으로 각기 다른 알림이 적절한 URL 만들도록 오버라이딩. .build(); } - public static NotificationResponse.PagedNotificationInfo toNotificationInfo( + public NotificationResponse.PagedNotificationInfo toNotificationInfo( Page notificationList){ List notificationInfoList - = notificationList.stream().map(NotificationConverter::notificationInfo).collect(Collectors.toList()); + = notificationList.stream().map(this::notificationInfo).collect(Collectors.toList()); return NotificationResponse.PagedNotificationInfo.builder() .isLast(notificationList.isLast()) @@ -34,30 +36,30 @@ public static NotificationResponse.PagedNotificationInfo toNotificationInfo( .build(); } - public static NotificationResponse.UnreadNotification toUnreadNotification(List notificationList){ - return NotificationResponse.UnreadNotification.builder() + public NotificationResponse.IsUnread toIsUnread(List notificationList){ + return NotificationResponse.IsUnread.builder() .isUnread(!notificationList.isEmpty()) .build(); } - public static NotificationResponse.NotificationAcknowledgeCount toNotificationAcknowledgedCount(List notificationList){ + public NotificationResponse.NotificationAcknowledgeCount toNotificationAcknowledgedCount(List notificationList){ return NotificationResponse.NotificationAcknowledgeCount.builder() .acknowledgedCount((long)notificationList.size()) .build(); } - public static NotificationResponse.NotificationAcknowledgeCount toNotificationAcknowledgedCount(Long updateCount){ + public NotificationResponse.NotificationAcknowledgeCount toNotificationAcknowledgedCount(Long updateCount){ return NotificationResponse.NotificationAcknowledgeCount.builder() .acknowledgedCount(updateCount) .build(); } - public static NotificationResponse.NotificationDeletedCount toNotificationDeletedCount(Long updateCount){ + public NotificationResponse.NotificationDeletedCount toNotificationDeletedCount(Long updateCount){ return NotificationResponse.NotificationDeletedCount.builder() .deletedCount(updateCount) .build(); } - public static DeviceToken toDeviceToken(Member member, NotificationRequest.FcmToken fcmToken){ + public DeviceToken toDeviceToken(Member member, NotificationRequest.FcmToken fcmToken){ return DeviceToken.builder() .member(member) .fcmToken(fcmToken.getToken()) diff --git a/src/main/java/com/umc/naoman/domain/notification/dto/NotificationResponse.java b/src/main/java/com/umc/naoman/domain/notification/dto/NotificationResponse.java index 6e1dccbc..54c6fc35 100644 --- a/src/main/java/com/umc/naoman/domain/notification/dto/NotificationResponse.java +++ b/src/main/java/com/umc/naoman/domain/notification/dto/NotificationResponse.java @@ -38,7 +38,7 @@ public static class NotificationInfo { @Getter @NoArgsConstructor @AllArgsConstructor - public static class UnreadNotification { + public static class IsUnread { Boolean isUnread; } diff --git a/src/main/java/com/umc/naoman/domain/notification/service/FcmService.java b/src/main/java/com/umc/naoman/domain/notification/service/FcmService.java index 37ee41e7..3d1cf515 100644 --- a/src/main/java/com/umc/naoman/domain/notification/service/FcmService.java +++ b/src/main/java/com/umc/naoman/domain/notification/service/FcmService.java @@ -1,5 +1,7 @@ package com.umc.naoman.domain.notification.service; +import com.umc.naoman.domain.member.entity.Member; + public interface FcmService { - void saveFcmToken(Long memberId, String fcmToken); + void saveFcmToken(Member member, String fcmToken); } diff --git a/src/main/java/com/umc/naoman/domain/notification/service/FcmServiceImpl.java b/src/main/java/com/umc/naoman/domain/notification/service/FcmServiceImpl.java index de8e0e75..2fe7a04b 100644 --- a/src/main/java/com/umc/naoman/domain/notification/service/FcmServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/notification/service/FcmServiceImpl.java @@ -1,5 +1,6 @@ package com.umc.naoman.domain.notification.service; +import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.notification.entity.DeviceToken; import com.umc.naoman.domain.notification.repository.FcmTokenRepository; import lombok.RequiredArgsConstructor; @@ -13,10 +14,9 @@ public class FcmServiceImpl implements FcmService{ private final FcmTokenRepository fcmTokenRepository; @Override - public void saveFcmToken(Long memberId, String fcmToken) { - //멤버 리파지토리 개발 후 수정해야됨 + public void saveFcmToken(Member member, String fcmToken) { DeviceToken deviceToken = DeviceToken.builder() - .member(null) + .member(member) .fcmToken(fcmToken) .build(); fcmTokenRepository.save(deviceToken); From a45d8175c8f209e787b53379f19642a0f689fc3e Mon Sep 17 00:00:00 2001 From: redblackblossom Date: Wed, 7 Aug 2024 17:37:10 +0900 Subject: [PATCH 03/18] =?UTF-8?q?refact=20:=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC,=20=EC=95=8C=EB=A6=BC=20?= =?UTF-8?q?=EC=BB=A8=EB=B2=84=ED=84=B0=20=ED=95=A8=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../notification/controller/NotificationController.java | 4 ++-- .../notification/converter/NotificationConverter.java | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java index 442f98f6..8ad8e62c 100644 --- a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java @@ -57,12 +57,12 @@ public ResultResponse registerFcmToken(@RequestBody NotificationRequest.Fc @Parameter(name = "size", description = "한 페이지에 나타낼 알림 개수를 입력해주세요.") }) @Operation(summary = "자신의 모든 알림 조회", description = "자신의 모든 알림을 조회하는 API입니다.") - public ResultResponse getNotifications(@LoginMember Member member, + public ResultResponse getNotificationList(@LoginMember Member member, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable){ Page notificationPage = notificationService.getNotificationList(member, pageable); return ResultResponse.of(NotificationResultCode.GET_MY_NOTIFICATION, - notificationConverter.toNotificationInfo(notificationPage)); + notificationConverter.toPagedNotificationInfo(notificationPage)); } @GetMapping("/unread") diff --git a/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java b/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java index 4b376230..50812760 100644 --- a/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java +++ b/src/main/java/com/umc/naoman/domain/notification/converter/NotificationConverter.java @@ -14,7 +14,7 @@ @Component public class NotificationConverter { - public NotificationResponse.NotificationInfo notificationInfo(Notification notification){ + public NotificationResponse.NotificationInfo toNotificationInfo(Notification notification){ return NotificationResponse.NotificationInfo.builder() .body(notification.getMessage()) .createdAt(notification.getCreatedAt()) @@ -22,10 +22,10 @@ public NotificationResponse.NotificationInfo notificationInfo(Notification notif .url(notification.makeNotificationInfoURL()) //다형성으로 각기 다른 알림이 적절한 URL 만들도록 오버라이딩. .build(); } - public NotificationResponse.PagedNotificationInfo toNotificationInfo( + public NotificationResponse.PagedNotificationInfo toPagedNotificationInfo( Page notificationList){ List notificationInfoList - = notificationList.stream().map(this::notificationInfo).collect(Collectors.toList()); + = notificationList.stream().map(this::toNotificationInfo).collect(Collectors.toList()); return NotificationResponse.PagedNotificationInfo.builder() .isLast(notificationList.isLast()) From 04a178953b7ae21065ada9f2db8dcaf5cfb1e5f0 Mon Sep 17 00:00:00 2001 From: bflykky Date: Wed, 7 Aug 2024 17:42:22 +0900 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20=EC=95=88=EA=B1=B4=EC=97=90=20?= =?UTF-8?q?=ED=88=AC=ED=91=9C=ED=95=98=EA=B8=B0=20API=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?,=20Vote=20=EC=97=94=ED=8B=B0=ED=8B=B0=EA=B0=80=20Member=20?= =?UTF-8?q?=EB=8C=80=EC=8B=A0=20Profile=EA=B3=BC=20=EC=97=B0=EA=B4=80?= =?UTF-8?q?=EA=B4=80=EA=B3=84=20=EA=B0=96=EB=8F=84=EB=A1=9D=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 --- .../vote/controller/VoteController.java | 33 +++++++++ .../domain/vote/converter/VoteConverter.java | 23 +++++++ .../naoman/domain/vote/dto/VoteRequest.java | 20 ++++++ .../naoman/domain/vote/dto/VoteResponse.java | 14 ++++ .../umc/naoman/domain/vote/entity/Vote.java | 6 +- .../vote/repository/VoteRepository.java | 10 +++ .../domain/vote/service/VoteService.java | 9 +++ .../domain/vote/service/VoteServiceImpl.java | 68 +++++++++++++++++++ .../global/error/code/AgendaErrorCode.java | 2 + .../global/error/code/VoteErrorCode.java | 18 +++++ .../global/result/code/VoteResultCode.java | 19 ++++++ 11 files changed, 219 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/service/VoteService.java create mode 100644 src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java create mode 100644 src/main/java/com/umc/naoman/global/error/code/VoteErrorCode.java create mode 100644 src/main/java/com/umc/naoman/global/result/code/VoteResultCode.java diff --git a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java new file mode 100644 index 00000000..62b8ed95 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java @@ -0,0 +1,33 @@ +package com.umc.naoman.domain.vote.controller; + +import com.umc.naoman.domain.member.entity.Member; +import com.umc.naoman.domain.vote.dto.VoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.service.VoteService; +import com.umc.naoman.global.result.ResultResponse; +import com.umc.naoman.global.security.annotation.LoginMember; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import static com.umc.naoman.global.result.code.VoteResultCode.GENERATE_VOTE; + +@RestController +@Tag(name = "안건에 대한 투표 관련 API", description = "안건에 대한 투표 행위를 관리하는 API입니다.") +@RequiredArgsConstructor +public class VoteController { + private final VoteService voteService; + + @PostMapping("/agendas/{agendaId}/vote") + public ResultResponse generateVote(@PathVariable("agendaId") Long agendaId, + @Valid @RequestBody VoteRequest.GenerateVoteRequest request, + @LoginMember Member member) { + return ResultResponse.of(GENERATE_VOTE, voteService.generateVote(agendaId, request, member)); + } + +} diff --git a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java new file mode 100644 index 00000000..bcb70007 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java @@ -0,0 +1,23 @@ +package com.umc.naoman.domain.vote.converter; + +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; +import com.umc.naoman.domain.shareGroup.entity.Profile; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.entity.Vote; +import org.springframework.stereotype.Component; + +@Component +public class VoteConverter { + public Vote toEntity(GenerateVoteRequest request, Profile profile, AgendaPhoto agendaPhoto) { + return Vote.builder() + .comment(request.getComment()) + .profile(profile) + .agendaPhoto(agendaPhoto) + .build(); + } + + public VoteId toVoteId(Long voteId) { + return new VoteId(voteId); + } +} diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java new file mode 100644 index 00000000..c5f447d0 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java @@ -0,0 +1,20 @@ +package com.umc.naoman.domain.vote.dto; + +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public abstract class VoteRequest { + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class GenerateVoteRequest { + // 코멘트 관련 길이 제한 + private String comment; + @NotNull(message = "투표하려는 안건의 사진에 대한 agendaPhotoId 값을 필수로 입력해 주세요.") + private Long agendaPhotoId; + } +} diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java new file mode 100644 index 00000000..a9569f34 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java @@ -0,0 +1,14 @@ +package com.umc.naoman.domain.vote.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public abstract class VoteResponse { + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class VoteId { + private Long voteId; + } +} diff --git a/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java b/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java index d3914de3..3bb8fe27 100644 --- a/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java +++ b/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java @@ -1,7 +1,7 @@ package com.umc.naoman.domain.vote.entity; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; -import com.umc.naoman.domain.member.entity.Member; +import com.umc.naoman.domain.shareGroup.entity.Profile; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EntityListeners; @@ -38,8 +38,8 @@ public class Vote { private Long id; private String comment; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; + @JoinColumn(name = "profile_id") + private Profile profile; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "agendas_photos_id") private AgendaPhoto agendaPhoto; diff --git a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java new file mode 100644 index 00000000..ad76c167 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java @@ -0,0 +1,10 @@ +package com.umc.naoman.domain.vote.repository; + +import com.umc.naoman.domain.vote.entity.Vote; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface VoteRepository extends JpaRepository { + Boolean existsByProfileIdAndAgendaPhotoId(Long profileId, Long agendaPhotoId); +} diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java new file mode 100644 index 00000000..cac04785 --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java @@ -0,0 +1,9 @@ +package com.umc.naoman.domain.vote.service; + +import com.umc.naoman.domain.member.entity.Member; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; + +public interface VoteService { + VoteId generateVote(Long agendaId, GenerateVoteRequest request, Member member); +} diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java new file mode 100644 index 00000000..9579e45b --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java @@ -0,0 +1,68 @@ +package com.umc.naoman.domain.vote.service; + +import com.umc.naoman.domain.agenda.entity.Agenda; +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; +import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository; +import com.umc.naoman.domain.agenda.service.AgendaService; +import com.umc.naoman.domain.member.entity.Member; +import com.umc.naoman.domain.shareGroup.entity.Profile; +import com.umc.naoman.domain.shareGroup.service.ShareGroupService; +import com.umc.naoman.domain.vote.converter.VoteConverter; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.entity.Vote; +import com.umc.naoman.domain.vote.repository.VoteRepository; +import com.umc.naoman.global.error.BusinessException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; +import static com.umc.naoman.global.error.code.VoteErrorCode.DUPLICATE_VOTE; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class VoteServiceImpl implements VoteService { + private final ShareGroupService shareGroupService; + private final AgendaService agendaService; + private final AgendaPhotoRepository agendaPhotoRepository; + private final VoteRepository voteRepository; + private final VoteConverter voteConverter; + + + /** + * 1. agendaId로 안건을 갖고 온다. (안건의 존재 여부 확인) + * 2. 갖고 온 안건에서 shareGroup 객체를 꺼낸다. + * 3. shareGroup.findProfile(Long shareGroupId, Long memberId)을 통해 투표를 요청한 사람의 프로필 id를 알아낸다. (프로필 존재 여부 확인) + * 4. request.getAgendaPhotoId() 값을 통해 회원이 투표하려고 한 agendaPhoto를 갖고 온다. (agendaPhoto 존재 여부 확인) + * 5. 이미 해당 안건의 해당 사진에 투표한 기록이 있는지 확인(중복 투표 방지) + * @param agendaId + * @param request + * @param member + * @return + */ + @Override + @Transactional + public VoteId generateVote(Long agendaId, GenerateVoteRequest request, Member member) { + Agenda agenda = agendaService.findAgenda(agendaId); + Profile profile = shareGroupService.findProfile(agenda.getShareGroup().getId(), member.getId()); + // 추후 findAgendaPhoto(Long agendaPhotoId)로 함수화 요청 예정. + AgendaPhoto agendaPhoto = agendaPhotoRepository.findById(request.getAgendaPhotoId()) + .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); + + checkDuplicateVote(profile, agendaPhoto); + Vote vote = voteConverter.toEntity(request, profile, agendaPhoto); + + voteRepository.save(vote); + return voteConverter.toVoteId(vote.getId()); + } + + private void checkDuplicateVote(Profile profile, AgendaPhoto agendaPhoto) { + if (voteRepository.existsByProfileIdAndAgendaPhotoId(profile.getId(), agendaPhoto.getId())) { + throw new BusinessException(DUPLICATE_VOTE); + } + } + + +} diff --git a/src/main/java/com/umc/naoman/global/error/code/AgendaErrorCode.java b/src/main/java/com/umc/naoman/global/error/code/AgendaErrorCode.java index c14042ed..fbd5601f 100644 --- a/src/main/java/com/umc/naoman/global/error/code/AgendaErrorCode.java +++ b/src/main/java/com/umc/naoman/global/error/code/AgendaErrorCode.java @@ -8,6 +8,8 @@ @RequiredArgsConstructor public enum AgendaErrorCode implements ErrorCode { AGENDA_NOT_FOUND_BY_AGENDA_ID(404, "EA001", "해당 agendaId를 가진 안건이 존재하지 않습니다."), + AGENDA_PHOTO_NOT_FOUND(404, "EA002", "해당 agendaPhotoId를 가진 안건 후보로 올라간 사진이 존재하지 않습니다."), + ; private final int status; diff --git a/src/main/java/com/umc/naoman/global/error/code/VoteErrorCode.java b/src/main/java/com/umc/naoman/global/error/code/VoteErrorCode.java new file mode 100644 index 00000000..be4aa2d4 --- /dev/null +++ b/src/main/java/com/umc/naoman/global/error/code/VoteErrorCode.java @@ -0,0 +1,18 @@ +package com.umc.naoman.global.error.code; + +import com.umc.naoman.global.error.ErrorCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum VoteErrorCode implements ErrorCode { + VOTE_NOT_FOUND(404, "EV001", "해당 voteId를 가진 투표가 존재하지 않습니다."), + DUPLICATE_VOTE(400, "EV002", "이미 해당 사진에 투표하였습니다."), + + ; + + private final int status; + private final String code; + private final String message; +} diff --git a/src/main/java/com/umc/naoman/global/result/code/VoteResultCode.java b/src/main/java/com/umc/naoman/global/result/code/VoteResultCode.java new file mode 100644 index 00000000..4d3776e0 --- /dev/null +++ b/src/main/java/com/umc/naoman/global/result/code/VoteResultCode.java @@ -0,0 +1,19 @@ +package com.umc.naoman.global.result.code; + +import com.umc.naoman.global.result.ResultCode; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum VoteResultCode implements ResultCode { + GENERATE_VOTE(200, "SV001", "특정 안건에 대하여 성공적으로 투표하였습니다."), + GET_VOTE_LIST(200, "SV002", "특정 안건에 대한 투표 목록을 성공적으로 조회하였습니다."), + DELETE_VOTE(200, "SV003", "특정 안건에 대한 투표를 성공적으로 삭제하였습니다."), + + ; + + private final int status; + private final String code; + private final String message; +} From 2542509ba6ce93a6408e2c511bb92b290027bdc5 Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 15:02:51 +0900 Subject: [PATCH 05/18] =?UTF-8?q?fix:=20=EC=95=88=EA=B1=B4=20=ED=88=AC?= =?UTF-8?q?=ED=91=9C=EC=8B=9C=20=ED=95=9C=20=EB=B2=88=EC=97=90=20=EC=97=AC?= =?UTF-8?q?=EB=9F=AC=20=EC=82=AC=EC=A7=84=EC=97=90=20=ED=88=AC=ED=91=9C?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=9E=88=EB=8F=84=EB=A1=9D=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 --- .../vote/controller/VoteController.java | 35 ++++++++++++---- .../domain/vote/converter/VoteConverter.java | 18 ++++++-- .../naoman/domain/vote/dto/VoteRequest.java | 15 ++++++- .../naoman/domain/vote/dto/VoteResponse.java | 28 +++++++++++++ .../domain/vote/service/VoteService.java | 6 +-- .../domain/vote/service/VoteServiceImpl.java | 42 +++++++++---------- 6 files changed, 107 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java index 62b8ed95..87a05435 100644 --- a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java +++ b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java @@ -1,15 +1,19 @@ package com.umc.naoman.domain.vote.controller; import com.umc.naoman.domain.member.entity.Member; -import com.umc.naoman.domain.vote.dto.VoteRequest; -import com.umc.naoman.domain.vote.dto.VoteResponse; -import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteInfo; import com.umc.naoman.domain.vote.service.VoteService; import com.umc.naoman.global.result.ResultResponse; import com.umc.naoman.global.security.annotation.LoginMember; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -18,16 +22,31 @@ import static com.umc.naoman.global.result.code.VoteResultCode.GENERATE_VOTE; @RestController -@Tag(name = "안건에 대한 투표 관련 API", description = "안건에 대한 투표 행위를 관리하는 API입니다.") +@Tag(name = "05. 투표 API", description = "안건에 대한 투표 행위를 관리하는 API입니다.") @RequiredArgsConstructor public class VoteController { private final VoteService voteService; @PostMapping("/agendas/{agendaId}/vote") - public ResultResponse generateVote(@PathVariable("agendaId") Long agendaId, - @Valid @RequestBody VoteRequest.GenerateVoteRequest request, - @LoginMember Member member) { - return ResultResponse.of(GENERATE_VOTE, voteService.generateVote(agendaId, request, member)); + @Operation(summary = "안건에 투표하기 API", description = "특정 안건에 대하여 투표하는 API입니다. 한 번에 여러 사진에 투표가 가능합니다.") + @Parameters(value = { + @Parameter(name = "agendaId", description = "투표를 진행할 안건의 agendaId를 입력해 주세요.") + }) + public ResultResponse generateVoteList(@PathVariable("agendaId") Long agendaId, + @Valid @RequestBody GenerateVoteListRequest request, + @LoginMember Member member) { + return ResultResponse.of(GENERATE_VOTE, voteService.generateVoteList(agendaId, request, member)); + } + + @GetMapping("/agendas/{agendaId}/vote") + @Operation(summary = "특정 안건의 투표 현황 조회 API", description = "특정 안건에 대한 투표 현항을 조회하는 API입니다.") + @Parameters(value = { + @Parameter(name = "agendaId", description = "투표 현황을 조회할 안건의 agendaId를 입력해 주세요.") + }) + public ResultResponse getVoteList(@PathVariable("agendaId") Long agendaId, + @LoginMember Member member) { +// return ResultResponse.of(GENERATE_VOTE, voteService.getVoteLIst(agendaId, member)); + return null; } } diff --git a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java index bcb70007..99a0a711 100644 --- a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java +++ b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java @@ -2,21 +2,33 @@ import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.shareGroup.entity.Profile; -import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; import com.umc.naoman.domain.vote.entity.Vote; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.stream.Collectors; + @Component public class VoteConverter { - public Vote toEntity(GenerateVoteRequest request, Profile profile, AgendaPhoto agendaPhoto) { + public Vote toEntity(String comment, Profile profile, AgendaPhoto agendaPhoto) { return Vote.builder() - .comment(request.getComment()) + .comment(comment) .profile(profile) .agendaPhoto(agendaPhoto) .build(); } + public VoteIdList toVoteIdList(List voteList) { + List voteIdList = voteList.stream() + .map(vote -> vote.getId()) + .collect(Collectors.toList()); + + return new VoteIdList(voteIdList); + } + public VoteId toVoteId(Long voteId) { return new VoteId(voteId); } diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java index c5f447d0..2965c84a 100644 --- a/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteRequest.java @@ -1,18 +1,31 @@ package com.umc.naoman.domain.vote.dto; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + public abstract class VoteRequest { + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class GenerateVoteListRequest { + @NotEmpty(message = "최소 1개의 투표를 한 후 요청해야 합니다.") + private List voteInfoList; + } + @Getter @Builder @NoArgsConstructor @AllArgsConstructor public static class GenerateVoteRequest { - // 코멘트 관련 길이 제한 + @Size(max = 15, message = "투표 코멘트는 최대 15자까지 작성할 수 있습니다.") private String comment; @NotNull(message = "투표하려는 안건의 사진에 대한 agendaPhotoId 값을 필수로 입력해 주세요.") private Long agendaPhotoId; diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java index a9569f34..c1b793b3 100644 --- a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java @@ -1,14 +1,42 @@ package com.umc.naoman.domain.vote.dto; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + public abstract class VoteResponse { + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class VoteIdList { + @Builder.Default + private List voteIdList = new ArrayList<>(); + } + @Getter @NoArgsConstructor @AllArgsConstructor public static class VoteId { private Long voteId; } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class VoteInfo { + private Long voteId; + private String comment; + private Long profileId; + private Long agendaPhotoId; + @JsonFormat(pattern = "yyy-MM-dd HH:mm:ss") + private LocalDateTime votedAt; + } } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java index cac04785..a1310b2d 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java @@ -1,9 +1,9 @@ package com.umc.naoman.domain.vote.service; import com.umc.naoman.domain.member.entity.Member; -import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; -import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; public interface VoteService { - VoteId generateVote(Long agendaId, GenerateVoteRequest request, Member member); + VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest request, Member member); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java index 9579e45b..531420ad 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java @@ -8,8 +8,9 @@ import com.umc.naoman.domain.shareGroup.entity.Profile; import com.umc.naoman.domain.shareGroup.service.ShareGroupService; import com.umc.naoman.domain.vote.converter.VoteConverter; +import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; -import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; import com.umc.naoman.domain.vote.entity.Vote; import com.umc.naoman.domain.vote.repository.VoteRepository; import com.umc.naoman.global.error.BusinessException; @@ -17,6 +18,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; +import java.util.stream.Collectors; + import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; import static com.umc.naoman.global.error.code.VoteErrorCode.DUPLICATE_VOTE; @@ -30,39 +34,33 @@ public class VoteServiceImpl implements VoteService { private final VoteRepository voteRepository; private final VoteConverter voteConverter; - - /** - * 1. agendaId로 안건을 갖고 온다. (안건의 존재 여부 확인) - * 2. 갖고 온 안건에서 shareGroup 객체를 꺼낸다. - * 3. shareGroup.findProfile(Long shareGroupId, Long memberId)을 통해 투표를 요청한 사람의 프로필 id를 알아낸다. (프로필 존재 여부 확인) - * 4. request.getAgendaPhotoId() 값을 통해 회원이 투표하려고 한 agendaPhoto를 갖고 온다. (agendaPhoto 존재 여부 확인) - * 5. 이미 해당 안건의 해당 사진에 투표한 기록이 있는지 확인(중복 투표 방지) - * @param agendaId - * @param request - * @param member - * @return - */ @Override @Transactional - public VoteId generateVote(Long agendaId, GenerateVoteRequest request, Member member) { - Agenda agenda = agendaService.findAgenda(agendaId); + public VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest request, Member member) { + Agenda agenda = agendaService.findAgenda(agendaId); // 안건의 존재 여부 확인 Profile profile = shareGroupService.findProfile(agenda.getShareGroup().getId(), member.getId()); - // 추후 findAgendaPhoto(Long agendaPhotoId)로 함수화 요청 예정. + + List voteList = request.getVoteInfoList().stream() + .map(voteInfo -> generateVote(voteInfo, profile)) + .collect(Collectors.toList()); + + voteRepository.saveAll(voteList); + return voteConverter.toVoteIdList(voteList); + } + + private Vote generateVote(GenerateVoteRequest request, Profile profile) { + // AgendaPhoto findAgendaPhoto(Long agendaPhotoId)로 함수화 예정 AgendaPhoto agendaPhoto = agendaPhotoRepository.findById(request.getAgendaPhotoId()) .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); checkDuplicateVote(profile, agendaPhoto); - Vote vote = voteConverter.toEntity(request, profile, agendaPhoto); - - voteRepository.save(vote); - return voteConverter.toVoteId(vote.getId()); + return voteConverter.toEntity(request.getComment(), profile, agendaPhoto); } + // 해당 사진에 대한 투표를 이미 했는지 확인한다 private void checkDuplicateVote(Profile profile, AgendaPhoto agendaPhoto) { if (voteRepository.existsByProfileIdAndAgendaPhotoId(profile.getId(), agendaPhoto.getId())) { throw new BusinessException(DUPLICATE_VOTE); } } - - } From f4e41572db661e64c23da27d221c019765905c86 Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 15:03:49 +0900 Subject: [PATCH 06/18] =?UTF-8?q?docs:=20=EC=8A=A4=EC=9B=A8=EA=B1=B0?= =?UTF-8?q?=EC=97=90=20=ED=91=9C=EC=8B=9C=EB=90=98=EB=8A=94=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=20API=EC=9D=98=20=EC=88=9C=EC=84=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/naoman/domain/agenda/controller/AgendaController.java | 2 ++ .../umc/naoman/domain/member/controller/AuthController.java | 2 +- .../umc/naoman/domain/member/controller/MemberController.java | 2 +- .../notification/controller/NotificationController.java | 4 +++- .../umc/naoman/domain/photo/controller/PhotoController.java | 2 +- .../domain/shareGroup/controller/ShareGroupController.java | 2 +- 6 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java index c4f0131c..5547aa00 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java +++ b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java @@ -14,6 +14,7 @@ import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController +@Tag(name = "04. 안건 관련 API", description = "안건 관련 API입니다.") @RequiredArgsConstructor @Slf4j public class AgendaController { diff --git a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java index 9a60aa71..bf13b9dd 100644 --- a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java +++ b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java @@ -30,7 +30,7 @@ @RestController @RequestMapping("/auth") -@Tag(name = "인증,인가 관련 API", description = "회원의 회원가입 및 로그인 등을 처리하는 API입니다.") +@Tag(name = "00. 인증,인가 관련 API", description = "회원의 회원가입 및 로그인 등을 처리하는 API입니다.") @RequiredArgsConstructor public class AuthController { private final MemberService memberService; diff --git a/src/main/java/com/umc/naoman/domain/member/controller/MemberController.java b/src/main/java/com/umc/naoman/domain/member/controller/MemberController.java index d619895e..e3090902 100644 --- a/src/main/java/com/umc/naoman/domain/member/controller/MemberController.java +++ b/src/main/java/com/umc/naoman/domain/member/controller/MemberController.java @@ -24,7 +24,7 @@ @RestController @RequestMapping("/members") -@Tag(name = "회원 API", description = "회원 도메인의 API입니다.") +@Tag(name = "01. 회원 API", description = "회원 도메인의 API입니다.") @RequiredArgsConstructor public class MemberController { private final MemberService memberService; diff --git a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java index 186b024c..b14b3fa7 100644 --- a/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java +++ b/src/main/java/com/umc/naoman/domain/notification/controller/NotificationController.java @@ -11,6 +11,7 @@ import com.umc.naoman.global.security.annotation.LoginMember; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -22,8 +23,9 @@ @RestController -@RequiredArgsConstructor @RequestMapping("/notifications") +@Tag(name = "06. 알림 관련 API", description = "나ㅇ만 서비스의 알림 관련 API입니다.") +@RequiredArgsConstructor public class NotificationController { private final NotificationService notificationService; diff --git a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java index 7fb48fd7..cca929b9 100644 --- a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java +++ b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java @@ -37,7 +37,7 @@ @RestController @RequestMapping("/photos") @RequiredArgsConstructor -@Tag(name = "사진 관련 API", description = "사진 업로드, 조회, 삭제, 다운로드를 처리하는 API입니다.") +@Tag(name = "03. 사진 관련 API", description = "사진 업로드, 조회, 삭제, 다운로드를 처리하는 API입니다.") public class PhotoController { private final PhotoService photoService; diff --git a/src/main/java/com/umc/naoman/domain/shareGroup/controller/ShareGroupController.java b/src/main/java/com/umc/naoman/domain/shareGroup/controller/ShareGroupController.java index d38379f8..7dd8be6e 100644 --- a/src/main/java/com/umc/naoman/domain/shareGroup/controller/ShareGroupController.java +++ b/src/main/java/com/umc/naoman/domain/shareGroup/controller/ShareGroupController.java @@ -35,7 +35,7 @@ @RestController @RequiredArgsConstructor @RequestMapping("/shareGroups") -@Tag(name = "공유그룹 관련 API", description = "공유그룹 생성, 참여, 조회, 삭제 등을 처리하는 API입니다.") +@Tag(name = "02. 공유그룹 관련 API", description = "공유그룹 생성, 참여, 조회, 삭제 등을 처리하는 API입니다.") public class ShareGroupController { private final ShareGroupService shareGroupService; private final ShareGroupConverter shareGroupConverter; From 8da8ee01049c304c91454c37712225b9696d2338 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EB=A0=B9?= Date: Thu, 8 Aug 2024 16:17:54 +0900 Subject: [PATCH 07/18] =?UTF-8?q?feat:=20findAgendaPhoto()=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../naoman/domain/agenda/service/AgendaService.java | 2 ++ .../domain/agenda/service/AgendaServiceImpl.java | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java index 8d6a1c47..31fe0a44 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java @@ -2,10 +2,12 @@ import com.umc.naoman.domain.agenda.dto.AgendaRequest; import com.umc.naoman.domain.agenda.entity.Agenda; +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.member.entity.Member; public interface AgendaService { Agenda findAgenda(Long agendaId); Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); + AgendaPhoto findAgendaPhoto(Long agendaPhotoId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index 17d90912..3c7b07ed 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -3,6 +3,8 @@ import com.umc.naoman.domain.agenda.converter.AgendaConverter; import com.umc.naoman.domain.agenda.dto.AgendaRequest; import com.umc.naoman.domain.agenda.entity.Agenda; +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; +import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository; import com.umc.naoman.domain.agenda.repository.AgendaRepository; import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.shareGroup.entity.Profile; @@ -14,11 +16,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; + @Service @RequiredArgsConstructor public class AgendaServiceImpl implements AgendaService { private final AgendaRepository agendaRepository; + private final AgendaPhotoRepository agendaPhotoRepository; private final ShareGroupService shareGroupService; private final AgendaPhotoService agendaPhotoService; private final AgendaConverter agendaConverter; @@ -41,4 +46,11 @@ public Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest requ return agendaRepository.save(newAgenda); } + + @Override + @Transactional(readOnly = true) + public AgendaPhoto findAgendaPhoto(Long agendaPhotoId) { + return agendaPhotoRepository.findById(agendaPhotoId) + .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); + } } From 2d7f5de137880e45733beeda2fb25a2ca4746ae9 Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 17:05:44 +0900 Subject: [PATCH 08/18] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20API=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=EC=BF=BC=EB=A6=AC=EC=8A=A4=ED=8A=B8=EB=A7=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=95=EB=B3=B4=20=EC=A0=84=EB=8B=AC?= =?UTF-8?q?=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - GET 요청이므로 Request Body 대신 쿼리스트링으로 방식을 변경하였다. --- .../domain/member/controller/AuthController.java | 10 ++++++++-- .../naoman/domain/member/service/MemberService.java | 2 +- .../domain/member/service/MemberServiceImpl.java | 4 ++-- .../naoman/global/result/code/MemberResultCode.java | 2 +- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java index bf13b9dd..b96a71ee 100644 --- a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java +++ b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java @@ -5,6 +5,7 @@ import com.umc.naoman.domain.member.dto.MemberRequest.SignupRequest; import com.umc.naoman.domain.member.dto.MemberResponse.CheckMemberRegistration; import com.umc.naoman.domain.member.dto.MemberResponse.LoginInfo; +import com.umc.naoman.domain.member.entity.SocialType; import com.umc.naoman.domain.member.service.MemberService; import com.umc.naoman.global.error.BusinessException; import com.umc.naoman.global.result.ResultResponse; @@ -64,7 +65,12 @@ public ResultResponse login(@Valid @RequestBody LoginRequest request) @GetMapping("/check-registration") @Operation(summary = "회원가입 여부 조회 API", description = "authId와 플랫폼명을 통해, 해당 정보와 일치하는 회원의 가입 여부를 조회하는 API입니다.") - public ResultResponse checkSignup(@Valid @RequestBody LoginRequest request) { - return ResultResponse.of(CHECK_MEMBER_REGISTRATION, memberService.checkRegistration(request)); + @Parameters(value = { + @Parameter(name = "socialType", description = "KAKAO, GOOGLE 중 하나를 입력해야 합니다."), + @Parameter(name = "authId", description = "로그인한 소셜 플랫폼에서 제공한 회원 번호를 입력해야 합니다.") + }) + public ResultResponse checkSignup(@RequestParam("socialType") SocialType socialType, + @RequestParam("authId") String authId) { + return ResultResponse.of(CHECK_MEMBER_REGISTRATION, memberService.checkRegistration(socialType, authId)); } } diff --git a/src/main/java/com/umc/naoman/domain/member/service/MemberService.java b/src/main/java/com/umc/naoman/domain/member/service/MemberService.java index da9cca45..ea65e2ba 100644 --- a/src/main/java/com/umc/naoman/domain/member/service/MemberService.java +++ b/src/main/java/com/umc/naoman/domain/member/service/MemberService.java @@ -13,7 +13,7 @@ public interface MemberService { LoginInfo signup(String tempMemberInfo, MarketingAgreedRequest request); LoginInfo signup(SignupRequest request); LoginInfo login(LoginRequest request); - CheckMemberRegistration checkRegistration(LoginRequest request); + CheckMemberRegistration checkRegistration(SocialType socialType, String authId); MemberInfo getMyInfo(Member member); Member findMember(Long memberId); Member findMember(SocialType socialType, String authId); diff --git a/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java b/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java index b46befbc..e85d29b9 100644 --- a/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java @@ -80,8 +80,8 @@ public LoginInfo login(LoginRequest request) { } @Override - public CheckMemberRegistration checkRegistration(LoginRequest request) { - boolean isRegistered = memberRepository.existsBySocialTypeAndAuthId(request.getSocialType(), request.getAuthId()); + public CheckMemberRegistration checkRegistration(SocialType socialType, String authId) { + boolean isRegistered = memberRepository.existsBySocialTypeAndAuthId(socialType, authId); return new CheckMemberRegistration(isRegistered); } diff --git a/src/main/java/com/umc/naoman/global/result/code/MemberResultCode.java b/src/main/java/com/umc/naoman/global/result/code/MemberResultCode.java index 430d6153..4d31ec57 100644 --- a/src/main/java/com/umc/naoman/global/result/code/MemberResultCode.java +++ b/src/main/java/com/umc/naoman/global/result/code/MemberResultCode.java @@ -11,7 +11,7 @@ public enum MemberResultCode implements ResultCode { LOGIN(200, "SM000", "성공적으로 로그인하였습니다."), MYPAGE_INFO(200, "SM001", "내 정보를 성공적으로 조회하였습니다."), EDIT_MYPAGE_INFO(200, "SM002", "내 정보를 성공적으로 수정하였습니다."), - CHECK_MEMBER_REGISTRATION(200, "SM000", "해당 이메일을 가진 회원의 가입 여부를 성공적으로 조회하였습니다."), + CHECK_MEMBER_REGISTRATION(200, "SM000", "해당 정보에 대응하는 회원의 가입 여부를 성공적으로 조회하였습니다."), MEMBER_INFO (200,"SM005","회원 정보를 성공적으로 조회하였습니다."), CHECK_MARKETING_AGREED(200,"SM006","마케팅동의여부를 성공적으로 조회하였습니다."), ; From 06cedc3a7e243a6eba9acac8ff1c354d283eb06e Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 20:30:57 +0900 Subject: [PATCH 09/18] =?UTF-8?q?feat:=20=ED=8A=B9=EC=A0=95=20=EC=95=88?= =?UTF-8?q?=EA=B1=B4=EC=9D=98=20=ED=88=AC=ED=91=9C=20=ED=98=84=ED=99=A9=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - agenda 도메인에 해당 API 구현 시 필요한 findAgendaPhoto(Long agendaPhotoId), findAgendaPhotoList(Long agendaId) 등을 구현하였다. --- .../repository/AgendaPhotoRepository.java | 3 ++ .../agenda/service/AgendaPhotoService.java | 4 ++ .../service/AgendaPhotoServiceImpl.java | 19 +++++++++- .../domain/agenda/service/AgendaService.java | 3 +- .../agenda/service/AgendaServiceImpl.java | 8 ---- .../shareGroup/service/ShareGroupService.java | 2 +- .../vote/controller/VoteController.java | 11 ++++-- .../domain/vote/converter/VoteConverter.java | 34 ++++++++++++++++- .../naoman/domain/vote/dto/VoteResponse.java | 18 ++++++++- .../vote/repository/VoteRepository.java | 3 ++ .../domain/vote/service/VoteService.java | 4 ++ .../domain/vote/service/VoteServiceImpl.java | 37 +++++++++++++++---- 12 files changed, 118 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaPhotoRepository.java b/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaPhotoRepository.java index 8c295210..0c1ac74d 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaPhotoRepository.java +++ b/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaPhotoRepository.java @@ -4,6 +4,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface AgendaPhotoRepository extends JpaRepository { + List findByAgendaId(Long agendaId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoService.java index a41722ed..219caa7c 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoService.java @@ -1,9 +1,13 @@ package com.umc.naoman.domain.agenda.service; import com.umc.naoman.domain.agenda.entity.Agenda; +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import java.util.List; public interface AgendaPhotoService { void saveAgendaPhotoList(Agenda agenda, List photos); + + AgendaPhoto findAgendaPhoto(Long agendaPhotoId); + List findAgendaPhotoList(Long agendaId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoServiceImpl.java index 48324b32..4f28b6c5 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaPhotoServiceImpl.java @@ -2,21 +2,25 @@ import com.umc.naoman.domain.agenda.converter.AgendaPhotoConverter; import com.umc.naoman.domain.agenda.entity.Agenda; +import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository; import com.umc.naoman.domain.photo.entity.Photo; import com.umc.naoman.domain.photo.service.PhotoService; +import com.umc.naoman.global.error.BusinessException; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; + @Service +@Transactional(readOnly = true) @RequiredArgsConstructor public class AgendaPhotoServiceImpl implements AgendaPhotoService { - - private final AgendaPhotoRepository agendaPhotoRepository; private final PhotoService photoService; + private final AgendaPhotoRepository agendaPhotoRepository; @Override @Transactional @@ -26,4 +30,15 @@ public void saveAgendaPhotoList(Agenda agenda, List photos) { agendaPhotoRepository.save(AgendaPhotoConverter.toEntity(agenda, photo)); } } + + @Override + public AgendaPhoto findAgendaPhoto(Long agendaPhotoId) { + return agendaPhotoRepository.findById(agendaPhotoId) + .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); + } + + @Override + public List findAgendaPhotoList(Long agendaId) { + return agendaPhotoRepository.findByAgendaId(agendaId); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java index 31fe0a44..297a9504 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java @@ -6,8 +6,7 @@ import com.umc.naoman.domain.member.entity.Member; public interface AgendaService { + Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); Agenda findAgenda(Long agendaId); - Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); - AgendaPhoto findAgendaPhoto(Long agendaPhotoId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index 3c7b07ed..1d94aa9e 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -23,7 +23,6 @@ public class AgendaServiceImpl implements AgendaService { private final AgendaRepository agendaRepository; - private final AgendaPhotoRepository agendaPhotoRepository; private final ShareGroupService shareGroupService; private final AgendaPhotoService agendaPhotoService; private final AgendaConverter agendaConverter; @@ -46,11 +45,4 @@ public Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest requ return agendaRepository.save(newAgenda); } - - @Override - @Transactional(readOnly = true) - public AgendaPhoto findAgendaPhoto(Long agendaPhotoId) { - return agendaPhotoRepository.findById(agendaPhotoId) - .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); - } } diff --git a/src/main/java/com/umc/naoman/domain/shareGroup/service/ShareGroupService.java b/src/main/java/com/umc/naoman/domain/shareGroup/service/ShareGroupService.java index 6c968beb..03938aa6 100644 --- a/src/main/java/com/umc/naoman/domain/shareGroup/service/ShareGroupService.java +++ b/src/main/java/com/umc/naoman/domain/shareGroup/service/ShareGroupService.java @@ -20,6 +20,6 @@ public interface ShareGroupService { List findProfileListByShareGroupId(Long shareGroupId); List findProfileListByMemberId(Long memberId); Profile findProfile(Long profileId); - Profile findProfile(Long shareGroupId, Long memberID); + Profile findProfile(Long shareGroupId, Long memberId); boolean doesProfileExist(Long shareGroupId, Long memberId); } diff --git a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java index 87a05435..a9c9f917 100644 --- a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java +++ b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java @@ -2,6 +2,8 @@ import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse; +import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteInfo; import com.umc.naoman.domain.vote.service.VoteService; @@ -19,6 +21,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + import static com.umc.naoman.global.result.code.VoteResultCode.GENERATE_VOTE; @RestController @@ -43,10 +47,9 @@ public ResultResponse generateVoteList(@PathVariable("agendaId") Lon @Parameters(value = { @Parameter(name = "agendaId", description = "투표 현황을 조회할 안건의 agendaId를 입력해 주세요.") }) - public ResultResponse getVoteList(@PathVariable("agendaId") Long agendaId, - @LoginMember Member member) { -// return ResultResponse.of(GENERATE_VOTE, voteService.getVoteLIst(agendaId, member)); - return null; + public ResultResponse> getVoteList(@PathVariable("agendaId") Long agendaId, + @LoginMember Member member) { + return ResultResponse.of(GENERATE_VOTE, voteService.getVoteList(agendaId, member)); } } diff --git a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java index 99a0a711..fa83865f 100644 --- a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java +++ b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java @@ -1,18 +1,25 @@ package com.umc.naoman.domain.vote.converter; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; +import com.umc.naoman.domain.shareGroup.converter.ShareGroupConverter; import com.umc.naoman.domain.shareGroup.entity.Profile; import com.umc.naoman.domain.vote.dto.VoteResponse; +import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteInfo; import com.umc.naoman.domain.vote.entity.Vote; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import java.util.List; import java.util.stream.Collectors; @Component +@RequiredArgsConstructor public class VoteConverter { + private final ShareGroupConverter shareGroupConverter; + public Vote toEntity(String comment, Profile profile, AgendaPhoto agendaPhoto) { return Vote.builder() .comment(comment) @@ -21,6 +28,10 @@ public Vote toEntity(String comment, Profile profile, AgendaPhoto agendaPhoto) { .build(); } + public VoteId toVoteId(Long voteId) { + return new VoteId(voteId); + } + public VoteIdList toVoteIdList(List voteList) { List voteIdList = voteList.stream() .map(vote -> vote.getId()) @@ -29,7 +40,26 @@ public VoteIdList toVoteIdList(List voteList) { return new VoteIdList(voteIdList); } - public VoteId toVoteId(Long voteId) { - return new VoteId(voteId); + public VoteInfo toVoteInfo(Vote vote, Profile viewerProfile) { + Long voterProfileId = vote.getProfile().getId(); + Long viewerProfileId = viewerProfile.getId(); + boolean isMine = voterProfileId.equals(viewerProfileId); + + return VoteInfo.builder() + .voteId(vote.getId()) + .comment(vote.getComment()) + .profileInfo(shareGroupConverter.toProfileInfo(vote.getProfile())) + .agendaPhotoId(vote.getAgendaPhoto().getId()) + .isMine(isMine) + .votedAt(vote.getVotedAt()) + .build(); + } + + public AgendaPhotoVoteDetails toAgendaPhotoVoteDetails(Long agendaPhotoId, List voteInfoList) { + return AgendaPhotoVoteDetails.builder() + .agendaPhotoId(agendaPhotoId) + .voteInfoList(voteInfoList) + .voteCount(voteInfoList.size()) + .build(); } } diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java index c1b793b3..8306a9f8 100644 --- a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java @@ -1,6 +1,8 @@ package com.umc.naoman.domain.vote.dto; import com.fasterxml.jackson.annotation.JsonFormat; +import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse; +import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.ProfileInfo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -34,9 +36,21 @@ public static class VoteId { public static class VoteInfo { private Long voteId; private String comment; - private Long profileId; + private ProfileInfo profileInfo; private Long agendaPhotoId; - @JsonFormat(pattern = "yyy-MM-dd HH:mm:ss") + private Boolean isMine; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime votedAt; } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AgendaPhotoVoteDetails { + private Long agendaPhotoId; + @Builder.Default + private List voteInfoList = new ArrayList<>(); + private int voteCount; + } } diff --git a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java index ad76c167..7ae7d74f 100644 --- a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java +++ b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java @@ -4,7 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface VoteRepository extends JpaRepository { Boolean existsByProfileIdAndAgendaPhotoId(Long profileId, Long agendaPhotoId); + List findByAgendaPhotoId(Long agendaPhotoId); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java index a1310b2d..f7d0e94f 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java @@ -2,8 +2,12 @@ import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; +import java.util.List; + public interface VoteService { VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest request, Member member); + List getVoteList(Long agendaId, Member member); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java index 531420ad..a6d89b9b 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java @@ -2,7 +2,7 @@ import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; -import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository; +import com.umc.naoman.domain.agenda.service.AgendaPhotoService; import com.umc.naoman.domain.agenda.service.AgendaService; import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.shareGroup.entity.Profile; @@ -10,7 +10,9 @@ import com.umc.naoman.domain.vote.converter.VoteConverter; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteRequest; +import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; +import com.umc.naoman.domain.vote.dto.VoteResponse.VoteInfo; import com.umc.naoman.domain.vote.entity.Vote; import com.umc.naoman.domain.vote.repository.VoteRepository; import com.umc.naoman.global.error.BusinessException; @@ -21,7 +23,6 @@ import java.util.List; import java.util.stream.Collectors; -import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; import static com.umc.naoman.global.error.code.VoteErrorCode.DUPLICATE_VOTE; @Service @@ -30,7 +31,7 @@ public class VoteServiceImpl implements VoteService { private final ShareGroupService shareGroupService; private final AgendaService agendaService; - private final AgendaPhotoRepository agendaPhotoRepository; + private final AgendaPhotoService agendaPhotoService; private final VoteRepository voteRepository; private final VoteConverter voteConverter; @@ -49,14 +50,36 @@ public VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest reques } private Vote generateVote(GenerateVoteRequest request, Profile profile) { - // AgendaPhoto findAgendaPhoto(Long agendaPhotoId)로 함수화 예정 - AgendaPhoto agendaPhoto = agendaPhotoRepository.findById(request.getAgendaPhotoId()) - .orElseThrow(() -> new BusinessException(AGENDA_PHOTO_NOT_FOUND)); - + AgendaPhoto agendaPhoto = agendaPhotoService.findAgendaPhoto(request.getAgendaPhotoId()); checkDuplicateVote(profile, agendaPhoto); + return voteConverter.toEntity(request.getComment(), profile, agendaPhoto); } + @Override + public List getVoteList(Long agendaId, Member member) { + Agenda agenda = agendaService.findAgenda(agendaId); // 안건 존재 여부 확인 + // 안건과 연관관계에 있는 공유그룹을 이용해 요청한 회원의 프로필을 가져온다 + // 해당 회원이 해당 공유 그룹의 그룹원인지도 확인 + Profile viewerProfile = shareGroupService.findProfile(agenda.getShareGroup().getId(), member.getId()); + + List agendaPhotoList = agendaPhotoService.findAgendaPhotoList(agendaId); + return agendaPhotoList.stream() + .map(agendaPhoto -> getVoteList(agendaPhoto.getId(), viewerProfile)) + .toList(); + } + + // 특정 안건 중 특정 사진에 대한 투표 목록 조회 + private AgendaPhotoVoteDetails getVoteList(Long agendaPhotoId, Profile viewerProfile) { + List voteList = voteRepository.findByAgendaPhotoId(agendaPhotoId); + + List voteInfoList = voteList.stream() + .map(vote -> voteConverter.toVoteInfo(vote, viewerProfile)) + .collect(Collectors.toList()); + + return voteConverter.toAgendaPhotoVoteDetails(agendaPhotoId, voteInfoList); + } + // 해당 사진에 대한 투표를 이미 했는지 확인한다 private void checkDuplicateVote(Profile profile, AgendaPhoto agendaPhoto) { if (voteRepository.existsByProfileIdAndAgendaPhotoId(profile.getId(), agendaPhoto.getId())) { From ca8609cbd03791573408d4abe3370be60788d382 Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 20:37:02 +0900 Subject: [PATCH 10/18] =?UTF-8?q?fix:=20=EC=8A=A4=EC=9B=A8=EA=B1=B0?= =?UTF-8?q?=EC=97=90=20pageable=20=EA=B0=9D=EC=B2=B4=EA=B0=80=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8F=84=EB=A1=9D=20hid?= =?UTF-8?q?den=20=EC=86=8D=EC=84=B1=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/photo/controller/PhotoController.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java index cca929b9..3a507a18 100644 --- a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java +++ b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java @@ -9,21 +9,16 @@ import com.umc.naoman.global.result.ResultResponse; import com.umc.naoman.global.security.annotation.LoginMember; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import org.springframework.core.io.ByteArrayResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.web.PageableDefault; -import org.springframework.http.ContentDisposition; -import org.springframework.http.HttpHeaders; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -61,7 +56,9 @@ public ResultResponse uploadPhotoList(@Valid @Req @GetMapping("/all") @Operation(summary = "특정 공유그룹의 전체 사진 조회 API", description = "특정 공유 그룹의 전체 사진을 조회하는 API입니다.") - public ResultResponse getAllPhotoListByShareGroup(@RequestParam Long shareGroupId, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable, + public ResultResponse getAllPhotoListByShareGroup(@RequestParam Long shareGroupId, + @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) + @Parameter(hidden = true) Pageable pageable, @LoginMember Member member) { Page allPhotoListByShareGroup = photoService.getAllPhotoList(shareGroupId, member, pageable); return ResultResponse.of(RETRIEVE_PHOTO, photoConverter.toPhotoListInfo(allPhotoListByShareGroup)); From 84f0ce17956cffd8e4242c17f340627eaab3b151 Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 20:38:01 +0900 Subject: [PATCH 11/18] =?UTF-8?q?docs:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20import=EB=AC=B8=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/umc/naoman/domain/vote/controller/VoteController.java | 2 -- .../com/umc/naoman/domain/vote/converter/VoteConverter.java | 1 - src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java | 1 - 3 files changed, 4 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java index a9c9f917..89b0c74f 100644 --- a/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java +++ b/src/main/java/com/umc/naoman/domain/vote/controller/VoteController.java @@ -2,10 +2,8 @@ import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; -import com.umc.naoman.domain.vote.dto.VoteResponse; import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; -import com.umc.naoman.domain.vote.dto.VoteResponse.VoteInfo; import com.umc.naoman.domain.vote.service.VoteService; import com.umc.naoman.global.result.ResultResponse; import com.umc.naoman.global.security.annotation.LoginMember; diff --git a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java index fa83865f..d9d05564 100644 --- a/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java +++ b/src/main/java/com/umc/naoman/domain/vote/converter/VoteConverter.java @@ -3,7 +3,6 @@ import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.shareGroup.converter.ShareGroupConverter; import com.umc.naoman.domain.shareGroup.entity.Profile; -import com.umc.naoman.domain.vote.dto.VoteResponse; import com.umc.naoman.domain.vote.dto.VoteResponse.AgendaPhotoVoteDetails; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteId; import com.umc.naoman.domain.vote.dto.VoteResponse.VoteIdList; diff --git a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java index 8306a9f8..ceabfe30 100644 --- a/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java +++ b/src/main/java/com/umc/naoman/domain/vote/dto/VoteResponse.java @@ -1,7 +1,6 @@ package com.umc.naoman.domain.vote.dto; import com.fasterxml.jackson.annotation.JsonFormat; -import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse; import com.umc.naoman.domain.shareGroup.dto.ShareGroupResponse.ProfileInfo; import lombok.AllArgsConstructor; import lombok.Builder; From 2c088629a8af7e8099cd81718fbde02902a29b2a Mon Sep 17 00:00:00 2001 From: bflykky Date: Thu, 8 Aug 2024 21:31:06 +0900 Subject: [PATCH 12/18] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20POST?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD,=20=EC=9A=94=EC=B2=AD=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=98=95=ED=83=9C=20request=20bo?= =?UTF-8?q?dy=EB=A1=9C=20=EB=A1=A4=EB=B0=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/AuthController.java | 11 +++-------- .../naoman/domain/member/service/MemberService.java | 2 +- .../domain/member/service/MemberServiceImpl.java | 4 ++-- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java index b96a71ee..c8866559 100644 --- a/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java +++ b/src/main/java/com/umc/naoman/domain/member/controller/AuthController.java @@ -63,14 +63,9 @@ public ResultResponse login(@Valid @RequestBody LoginRequest request) return ResultResponse.of(LOGIN, memberService.login(request)); } - @GetMapping("/check-registration") + @PostMapping("/check-registration") @Operation(summary = "회원가입 여부 조회 API", description = "authId와 플랫폼명을 통해, 해당 정보와 일치하는 회원의 가입 여부를 조회하는 API입니다.") - @Parameters(value = { - @Parameter(name = "socialType", description = "KAKAO, GOOGLE 중 하나를 입력해야 합니다."), - @Parameter(name = "authId", description = "로그인한 소셜 플랫폼에서 제공한 회원 번호를 입력해야 합니다.") - }) - public ResultResponse checkSignup(@RequestParam("socialType") SocialType socialType, - @RequestParam("authId") String authId) { - return ResultResponse.of(CHECK_MEMBER_REGISTRATION, memberService.checkRegistration(socialType, authId)); + public ResultResponse checkSignup(@Valid @RequestBody LoginRequest request) { + return ResultResponse.of(CHECK_MEMBER_REGISTRATION, memberService.checkRegistration(request)); } } diff --git a/src/main/java/com/umc/naoman/domain/member/service/MemberService.java b/src/main/java/com/umc/naoman/domain/member/service/MemberService.java index ea65e2ba..da9cca45 100644 --- a/src/main/java/com/umc/naoman/domain/member/service/MemberService.java +++ b/src/main/java/com/umc/naoman/domain/member/service/MemberService.java @@ -13,7 +13,7 @@ public interface MemberService { LoginInfo signup(String tempMemberInfo, MarketingAgreedRequest request); LoginInfo signup(SignupRequest request); LoginInfo login(LoginRequest request); - CheckMemberRegistration checkRegistration(SocialType socialType, String authId); + CheckMemberRegistration checkRegistration(LoginRequest request); MemberInfo getMyInfo(Member member); Member findMember(Long memberId); Member findMember(SocialType socialType, String authId); diff --git a/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java b/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java index e85d29b9..b46befbc 100644 --- a/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/member/service/MemberServiceImpl.java @@ -80,8 +80,8 @@ public LoginInfo login(LoginRequest request) { } @Override - public CheckMemberRegistration checkRegistration(SocialType socialType, String authId) { - boolean isRegistered = memberRepository.existsBySocialTypeAndAuthId(socialType, authId); + public CheckMemberRegistration checkRegistration(LoginRequest request) { + boolean isRegistered = memberRepository.existsBySocialTypeAndAuthId(request.getSocialType(), request.getAuthId()); return new CheckMemberRegistration(isRegistered); } From 17684bcd36347711dc64638236f20bbd407503a9 Mon Sep 17 00:00:00 2001 From: bflykky Date: Fri, 9 Aug 2024 11:21:03 +0900 Subject: [PATCH 13/18] =?UTF-8?q?fix:=20=EC=82=AC=EC=A7=84=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=ED=8C=8C=EB=9D=BC=EB=AF=B8?= =?UTF-8?q?=ED=84=B0=20=EC=9E=85=EB=A0=A5=ED=95=A0=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=8A=A4=EC=9B=A8=EA=B1=B0=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95,=20=EC=9D=91=EB=8B=B5=20=EB=8D=B0=EC=9D=B4=ED=84=B0?= =?UTF-8?q?=EC=97=90=20photoId=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../umc/naoman/domain/agenda/service/AgendaServiceImpl.java | 4 ++-- .../umc/naoman/domain/photo/controller/PhotoController.java | 5 +++++ .../umc/naoman/domain/photo/converter/PhotoConverter.java | 1 + .../java/com/umc/naoman/domain/photo/dto/PhotoResponse.java | 1 + 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index 1d94aa9e..f9f48695 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -40,8 +40,8 @@ public Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest requ Long shareGroupId = request.getShareGroupId(); ShareGroup shareGroup = shareGroupService.findShareGroup(shareGroupId); Profile profile = shareGroupService.findProfile(shareGroupId, member.getId()); - Agenda newAgenda = agendaConverter.toEntity(profile,request.getTitle(),shareGroup); - agendaPhotoService.saveAgendaPhotoList(newAgenda,request.getAgendasPhotoList()); + Agenda newAgenda = agendaConverter.toEntity(profile, request.getTitle(),shareGroup); + agendaPhotoService.saveAgendaPhotoList(newAgenda, request.getAgendasPhotoList()); return agendaRepository.save(newAgenda); } diff --git a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java index 3a507a18..41ef017c 100644 --- a/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java +++ b/src/main/java/com/umc/naoman/domain/photo/controller/PhotoController.java @@ -10,6 +10,7 @@ import com.umc.naoman.global.security.annotation.LoginMember; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -56,6 +57,10 @@ public ResultResponse uploadPhotoList(@Valid @Req @GetMapping("/all") @Operation(summary = "특정 공유그룹의 전체 사진 조회 API", description = "특정 공유 그룹의 전체 사진을 조회하는 API입니다.") + @Parameters(value = { + @Parameter(name = "page", description = "조회할 페이지를 입력해 주세요.(0번부터 시작)"), + @Parameter(name = "size", description = "한 페이지에 나타낼 사진 개수를 입력해주세요.") + }) public ResultResponse getAllPhotoListByShareGroup(@RequestParam Long shareGroupId, @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) @Parameter(hidden = true) Pageable pageable, diff --git a/src/main/java/com/umc/naoman/domain/photo/converter/PhotoConverter.java b/src/main/java/com/umc/naoman/domain/photo/converter/PhotoConverter.java index 78f7411d..2fbe0dc0 100644 --- a/src/main/java/com/umc/naoman/domain/photo/converter/PhotoConverter.java +++ b/src/main/java/com/umc/naoman/domain/photo/converter/PhotoConverter.java @@ -62,6 +62,7 @@ public PhotoResponse.PhotoInfo toPhotoInfo(Photo photo) { String rawUrl = photo.getUrl(); return PhotoResponse.PhotoInfo.builder() + .photoId(photo.getId()) .rawPhotoUrl(rawUrl) .w200PhotoUrl(createResizedPhotoUrl(rawUrl, W200_PATH_PREFIX)) .w400PhotoUrl(createResizedPhotoUrl(rawUrl, W400_PATH_PREFIX)) diff --git a/src/main/java/com/umc/naoman/domain/photo/dto/PhotoResponse.java b/src/main/java/com/umc/naoman/domain/photo/dto/PhotoResponse.java index 35dad94e..cd5a5538 100644 --- a/src/main/java/com/umc/naoman/domain/photo/dto/PhotoResponse.java +++ b/src/main/java/com/umc/naoman/domain/photo/dto/PhotoResponse.java @@ -56,6 +56,7 @@ public static class PagedPhotoInfo { @AllArgsConstructor @NoArgsConstructor public static class PhotoInfo { + private Long photoId; private String rawPhotoUrl; private String w200PhotoUrl; private String w400PhotoUrl; From 075504009556156f6ff9d54337ebb4e417d7d64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EB=A0=B9?= Date: Fri, 9 Aug 2024 22:42:45 +0900 Subject: [PATCH 14/18] =?UTF-8?q?feat:=20=EC=95=88=EA=B1=B4=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agenda/controller/AgendaController.java | 21 ++++++++++++++++++- .../agenda/converter/AgendaConverter.java | 21 +++++++++++++++++++ .../converter/AgendaPhotoConverter.java | 11 ++++++++++ .../agenda/dto/AgendaPhotoResponse.java | 18 ++++++++++++++++ .../domain/agenda/dto/AgendaRequest.java | 2 +- .../domain/agenda/dto/AgendaResponse.java | 13 ++++++++++++ .../naoman/domain/agenda/entity/Agenda.java | 8 +++++++ .../domain/agenda/service/AgendaService.java | 2 +- .../agenda/service/AgendaServiceImpl.java | 19 +++++++++++++---- .../umc/naoman/domain/vote/entity/Vote.java | 2 +- .../global/result/code/AgendaResultCode.java | 1 + .../global/security/util/CookieUtils.java | 6 +++--- 12 files changed, 113 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/umc/naoman/domain/agenda/dto/AgendaPhotoResponse.java diff --git a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java index 5547aa00..20f390d7 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java +++ b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java @@ -11,6 +11,8 @@ import com.umc.naoman.global.result.code.AgendaResultCode; import com.umc.naoman.global.security.annotation.LoginMember; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponses; @@ -18,11 +20,15 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@RequestMapping("/agendas") @Tag(name = "04. 안건 관련 API", description = "안건 관련 API입니다.") @RequiredArgsConstructor @Slf4j @@ -31,7 +37,7 @@ public class AgendaController { private final AgendaService agendaService; private final AgendaConverter agendaConverter; - @PostMapping("/agendas") + @PostMapping @Operation(summary = "안건 생성 API", description = "[request]\n shareGroupId, title, 안건에 올릴 PhotoId 리스트" + "\n[response]\n 생성된 안건의 agendaId, 생성시간 createdAt") @ApiResponses({ @@ -48,5 +54,18 @@ public ResultResponse createAgenda(@RequestBody @Vali Agenda agenda = agendaService.createAgenda(member,request); return ResultResponse.of(AgendaResultCode.CREATE_AGENDA, agendaConverter.toAgendaInfo(agenda)); } + + @GetMapping("/{agendaId}") + @Operation(summary = "안건 상세 조회 API", description = "agendaId로 안건 상세를 조회하는 API입니다.") + @Parameters(value = { + @Parameter(name = "agendaId", description = "특정 안건 id를 입력해 주세요.") + }) + public ResultResponse getAgendaDetail(@PathVariable(name = "agendaId") Long agendaId, + @LoginMember Member member) { + Agenda agenda = agendaService.getAgendaDetailInfo(agendaId, member); + + return ResultResponse.of(AgendaResultCode.AGENDA_DETAIL, + agendaConverter.toAgendaDetailInfo(agenda)); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java index 45f0cf7e..78a30c98 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java +++ b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java @@ -1,14 +1,22 @@ package com.umc.naoman.domain.agenda.converter; +import com.umc.naoman.domain.agenda.dto.AgendaPhotoResponse; import com.umc.naoman.domain.agenda.dto.AgendaResponse; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.shareGroup.entity.Profile; import com.umc.naoman.domain.shareGroup.entity.ShareGroup; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; +import java.util.List; +import java.util.stream.Collectors; + @Component +@RequiredArgsConstructor public class AgendaConverter { + private final AgendaPhotoConverter agendaPhotoConverter; + public AgendaResponse.AgendaInfo toAgendaInfo(Agenda agenda){ return AgendaResponse.AgendaInfo.builder() .agendaId(agenda.getId()) @@ -23,4 +31,17 @@ public Agenda toEntity(Profile profile, String title, ShareGroup shareGroup){ .shareGroup(shareGroup) .build(); } + + public AgendaResponse.AgendaDetailInfo toAgendaDetailInfo(Agenda agenda) { + List agendaPhotoInfoList = agenda.getAgendaPhotoList() + .stream() + .map(agendaPhotoConverter::toAgendaPhotoInfo) + .collect(Collectors.toList()); + + return AgendaResponse.AgendaDetailInfo.builder() + .agendaId(agenda.getId()) + .title(agenda.getTitle()) + .agendaPhotoInfoList(agendaPhotoInfoList) + .build(); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaPhotoConverter.java b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaPhotoConverter.java index 1e3faf55..b4eb00d0 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaPhotoConverter.java +++ b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaPhotoConverter.java @@ -1,9 +1,12 @@ package com.umc.naoman.domain.agenda.converter; +import com.umc.naoman.domain.agenda.dto.AgendaPhotoResponse; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.photo.entity.Photo; +import org.springframework.stereotype.Component; +@Component public class AgendaPhotoConverter { public static AgendaPhoto toEntity(Agenda agenda, Photo photo) { @@ -12,4 +15,12 @@ public static AgendaPhoto toEntity(Agenda agenda, Photo photo) { .photo(photo) .build(); } + + public AgendaPhotoResponse.AgendaPhotoInfo toAgendaPhotoInfo(AgendaPhoto agendaPhoto) { + return AgendaPhotoResponse.AgendaPhotoInfo + .builder() + .agendaPhotoId(agendaPhoto.getId()) + .url(agendaPhoto.getPhoto().getUrl()) + .build(); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaPhotoResponse.java b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaPhotoResponse.java new file mode 100644 index 00000000..25ece9df --- /dev/null +++ b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaPhotoResponse.java @@ -0,0 +1,18 @@ +package com.umc.naoman.domain.agenda.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public abstract class AgendaPhotoResponse { + + @Builder + @Getter + @NoArgsConstructor + @AllArgsConstructor + public static class AgendaPhotoInfo { + private Long agendaPhotoId; + private String url; + } +} diff --git a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaRequest.java b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaRequest.java index 78520c13..4117c9e1 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaRequest.java +++ b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaRequest.java @@ -21,6 +21,6 @@ public static class CreateAgendaRequest { @NotNull private String title; @Size(min = 2, max = 6, message = "안건에 등록하는 사진은 최소 2개 최대 6개로 한정 시켜 주세요.") - private List agendasPhotoList; + private List photoIdList; } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java index 64482756..18fbb320 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java +++ b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java @@ -1,11 +1,14 @@ package com.umc.naoman.domain.agenda.dto; import com.fasterxml.jackson.annotation.JsonFormat; +import com.umc.naoman.domain.agenda.dto.AgendaPhotoResponse.AgendaPhotoInfo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import java.time.LocalDateTime; +import java.util.List; public abstract class AgendaResponse { @@ -17,4 +20,14 @@ public static class AgendaInfo { @JsonFormat(pattern = "yyyy-MM-dd") private LocalDateTime createdAt; } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class AgendaDetailInfo { + private Long agendaId; + private String title; + private List agendaPhotoInfoList; + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java b/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java index db0ad566..a0f75b30 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java +++ b/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java @@ -7,6 +7,7 @@ import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import jakarta.persistence.Column; import jakarta.persistence.ManyToOne; @@ -20,6 +21,9 @@ import lombok.NoArgsConstructor; import org.hibernate.annotations.SQLRestriction; +import java.util.ArrayList; +import java.util.List; + @Entity @Table(name = "agendas") @SQLRestriction("deleted_at is NULL") @@ -40,4 +44,8 @@ public class Agenda extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "profile_id") private Profile profile; + + @OneToMany(mappedBy = "agenda") + @Builder.Default + private List agendaPhotoList = new ArrayList<>(); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java index 297a9504..89dce987 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java @@ -7,6 +7,6 @@ public interface AgendaService { Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); - Agenda findAgenda(Long agendaId); + Agenda getAgendaDetailInfo(Long agendaId, Member member); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index f9f48695..e7256904 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -2,9 +2,9 @@ import com.umc.naoman.domain.agenda.converter.AgendaConverter; import com.umc.naoman.domain.agenda.dto.AgendaRequest; +import com.umc.naoman.domain.agenda.dto.AgendaRequest.CreateAgendaRequest; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; -import com.umc.naoman.domain.agenda.repository.AgendaPhotoRepository; import com.umc.naoman.domain.agenda.repository.AgendaRepository; import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.shareGroup.entity.Profile; @@ -16,7 +16,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import static com.umc.naoman.global.error.code.AgendaErrorCode.AGENDA_PHOTO_NOT_FOUND; +import java.util.List; @Service @RequiredArgsConstructor @@ -36,13 +36,24 @@ public Agenda findAgenda(Long agendaId) { @Override @Transactional - public Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request) { + public Agenda createAgenda(Member member, CreateAgendaRequest request) { Long shareGroupId = request.getShareGroupId(); ShareGroup shareGroup = shareGroupService.findShareGroup(shareGroupId); Profile profile = shareGroupService.findProfile(shareGroupId, member.getId()); Agenda newAgenda = agendaConverter.toEntity(profile, request.getTitle(),shareGroup); - agendaPhotoService.saveAgendaPhotoList(newAgenda, request.getAgendasPhotoList()); + agendaPhotoService.saveAgendaPhotoList(newAgenda, request.getPhotoIdList()); return agendaRepository.save(newAgenda); } + + @Override + @Transactional(readOnly = true) + public Agenda getAgendaDetailInfo(Long agendaId, Member member) { + Agenda agenda = findAgenda(agendaId); + + shareGroupService.findProfile(agenda.getShareGroup().getId(), + member.getId()); + + return agenda; + } } diff --git a/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java b/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java index 3bb8fe27..0ab3d29d 100644 --- a/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java +++ b/src/main/java/com/umc/naoman/domain/vote/entity/Vote.java @@ -26,7 +26,7 @@ @Entity @EntityListeners(AuditingEntityListener.class) @Table(name = "votes") -@SQLRestriction("deleted_at is NULL") +@SQLRestriction("canceled_at is NULL") @Getter @Builder @NoArgsConstructor(access = AccessLevel.PROTECTED) diff --git a/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java b/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java index b19acd24..dbc178e3 100644 --- a/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java +++ b/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java @@ -8,6 +8,7 @@ @RequiredArgsConstructor public enum AgendaResultCode implements ResultCode { CREATE_AGENDA(200, "SA001", "새로운 안건을 성공적으로 생성하였습니다."), + AGENDA_DETAIL(200, "SA002", "상세 안건을 성공적으로 조회했습니다.") ; private final int status; private final String code; diff --git a/src/main/java/com/umc/naoman/global/security/util/CookieUtils.java b/src/main/java/com/umc/naoman/global/security/util/CookieUtils.java index eba6a9ae..2d8e3f06 100644 --- a/src/main/java/com/umc/naoman/global/security/util/CookieUtils.java +++ b/src/main/java/com/umc/naoman/global/security/util/CookieUtils.java @@ -16,9 +16,9 @@ public static void addCookie(HttpServletResponse response, String name, String v ResponseCookie cookie = ResponseCookie.from(name, value) .path("/") .maxAge(maxAge) - .httpOnly(false) - .secure(true) - .sameSite("None") + //.httpOnly(false) + //.secure(true) + //.sameSite("None") .build(); response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString()); From 8c799fbe795212f811fb7fb0eb6baf0a760a975f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EB=A0=B9?= Date: Fri, 9 Aug 2024 23:11:40 +0900 Subject: [PATCH 15/18] =?UTF-8?q?feature:=20=EC=95=88=EA=B1=B4=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=A4=91=EA=B0=84=20=EC=BB=A4=EB=B0=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/agenda/controller/AgendaController.java | 1 + .../com/umc/naoman/domain/agenda/entity/Agenda.java | 9 +++++++++ .../naoman/domain/agenda/service/AgendaService.java | 1 + .../domain/agenda/service/AgendaServiceImpl.java | 11 ++++++++++- .../naoman/domain/shareGroup/entity/ShareGroup.java | 2 +- 5 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java index 20f390d7..070b46e5 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java +++ b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java @@ -20,6 +20,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; diff --git a/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java b/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java index a0f75b30..feb08eb8 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java +++ b/src/main/java/com/umc/naoman/domain/agenda/entity/Agenda.java @@ -2,6 +2,7 @@ import com.umc.naoman.domain.shareGroup.entity.Profile; import com.umc.naoman.domain.shareGroup.entity.ShareGroup; +import com.umc.naoman.domain.vote.entity.Vote; import com.umc.naoman.global.entity.BaseTimeEntity; import jakarta.persistence.Entity; @@ -48,4 +49,12 @@ public class Agenda extends BaseTimeEntity { @OneToMany(mappedBy = "agenda") @Builder.Default private List agendaPhotoList = new ArrayList<>(); + + public void delete() { + //agendaPhoto 삭제 + for (AgendaPhoto agendaPhoto : agendaPhotoList) { + agendaPhoto.delete(); + } + super.delete(); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java index 89dce987..9ea95622 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java @@ -9,4 +9,5 @@ public interface AgendaService { Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); Agenda findAgenda(Long agendaId); Agenda getAgendaDetailInfo(Long agendaId, Member member); + Agenda deleteAgenda(Long agendaId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index e7256904..377dce37 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -56,4 +56,13 @@ public Agenda getAgendaDetailInfo(Long agendaId, Member member) { return agenda; } -} + + @Override + @Transactional + public Agenda deleteAgenda(Long agendaId) { + Agenda agenda = findAgenda(agendaId); + + agenda.delete(); + return agenda; + } +} \ No newline at end of file diff --git a/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java b/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java index 6070729d..caacf503 100644 --- a/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java +++ b/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java @@ -41,9 +41,9 @@ public class ShareGroup extends BaseTimeEntity { private List profiles = new ArrayList<>(); public void delete() { - super.delete(); for (Profile profile : profiles) { profile.delete(); } + super.delete(); } } From 4ceeb8168cb2aaad6cfa772e378d8c6b8b03c8a3 Mon Sep 17 00:00:00 2001 From: bflykky Date: Fri, 9 Aug 2024 23:13:23 +0900 Subject: [PATCH 16/18] =?UTF-8?q?feat:=20=ED=88=AC=ED=91=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vote/repository/VoteRepository.java | 6 +++++ .../domain/vote/service/VoteService.java | 1 + .../domain/vote/service/VoteServiceImpl.java | 25 ++++++++++++++++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java index 7ae7d74f..ae1d525e 100644 --- a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java +++ b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java @@ -2,6 +2,8 @@ import com.umc.naoman.domain.vote.entity.Vote; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import java.util.List; @@ -10,4 +12,8 @@ public interface VoteRepository extends JpaRepository { Boolean existsByProfileIdAndAgendaPhotoId(Long profileId, Long agendaPhotoId); List findByAgendaPhotoId(Long agendaPhotoId); + List findByAgendaPhotoIdIn(List agendaPhotoIdList); + @Modifying + @Query("DELETE FROM Vote AS v WHERE v.agendaPhoto.id IN :agendaPhotoIdList") + void deleteByAgendaPhotoIdIn(List agendaPhotoIdList); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java index f7d0e94f..eaa6d715 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java @@ -10,4 +10,5 @@ public interface VoteService { VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest request, Member member); List getVoteList(Long agendaId, Member member); + void deleteVoteList(Long agendaId, Member member); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java index a6d89b9b..5183b46a 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java @@ -6,6 +6,7 @@ import com.umc.naoman.domain.agenda.service.AgendaService; import com.umc.naoman.domain.member.entity.Member; import com.umc.naoman.domain.shareGroup.entity.Profile; +import com.umc.naoman.domain.shareGroup.entity.Role; import com.umc.naoman.domain.shareGroup.service.ShareGroupService; import com.umc.naoman.domain.vote.converter.VoteConverter; import com.umc.naoman.domain.vote.dto.VoteRequest.GenerateVoteListRequest; @@ -56,6 +57,13 @@ private Vote generateVote(GenerateVoteRequest request, Profile profile) { return voteConverter.toEntity(request.getComment(), profile, agendaPhoto); } + // 해당 사진에 대한 투표를 이미 했는지 확인한다 + private void checkDuplicateVote(Profile profile, AgendaPhoto agendaPhoto) { + if (voteRepository.existsByProfileIdAndAgendaPhotoId(profile.getId(), agendaPhoto.getId())) { + throw new BusinessException(DUPLICATE_VOTE); + } + } + @Override public List getVoteList(Long agendaId, Member member) { Agenda agenda = agendaService.findAgenda(agendaId); // 안건 존재 여부 확인 @@ -80,10 +88,19 @@ private AgendaPhotoVoteDetails getVoteList(Long agendaPhotoId, Profile viewerPro return voteConverter.toAgendaPhotoVoteDetails(agendaPhotoId, voteInfoList); } - // 해당 사진에 대한 투표를 이미 했는지 확인한다 - private void checkDuplicateVote(Profile profile, AgendaPhoto agendaPhoto) { - if (voteRepository.existsByProfileIdAndAgendaPhotoId(profile.getId(), agendaPhoto.getId())) { - throw new BusinessException(DUPLICATE_VOTE); + @Override + public void deleteVoteList(Long agendaId, Member member) { + Agenda agenda = agendaService.findAgenda(agendaId); // 안건 존재 여부 확인 + // 삭제하려는 사람의 프로필 조회 + Profile removerProfile = shareGroupService.findProfile(agenda.getShareGroup().getId(), member.getId()); + if (!Role.CREATOR.equals(removerProfile.getRole())) { + throw new BusinessException(null); } + + List agendaPhotoIdList = agendaPhotoService.findAgendaPhotoList(agendaId).stream() + .map(agendaPhoto -> agendaPhoto.getId()) + .toList(); + + voteRepository.deleteByAgendaPhotoIdIn(agendaPhotoIdList); } } From ce2424f38858fa44df01681f6686b6a8da023666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EB=A0=B9?= Date: Fri, 9 Aug 2024 23:22:39 +0900 Subject: [PATCH 17/18] =?UTF-8?q?fix:=20=ED=88=AC=ED=91=9C=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20soft=20delete=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/agenda/entity/AgendaPhoto.java | 18 +++++++++++++++++- .../domain/vote/repository/VoteRepository.java | 3 --- .../domain/vote/service/VoteService.java | 1 - .../domain/vote/service/VoteServiceImpl.java | 16 ---------------- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/entity/AgendaPhoto.java b/src/main/java/com/umc/naoman/domain/agenda/entity/AgendaPhoto.java index 026298ae..e09f69b1 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/entity/AgendaPhoto.java +++ b/src/main/java/com/umc/naoman/domain/agenda/entity/AgendaPhoto.java @@ -1,11 +1,15 @@ package com.umc.naoman.domain.agenda.entity; import com.umc.naoman.domain.photo.entity.Photo; +import com.umc.naoman.domain.vote.entity.Vote; import com.umc.naoman.global.entity.BaseTimeEntity; import jakarta.persistence.*; import lombok.*; import org.hibernate.annotations.SQLRestriction; +import java.util.ArrayList; +import java.util.List; + @Entity @Table(name = "agendas_photos") @SQLRestriction("deleted_at is NULL") @@ -24,4 +28,16 @@ public class AgendaPhoto extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "photo_id") private Photo photo; -} + + @OneToMany(mappedBy = "agendaPhoto") + @Builder.Default + private List voteList = new ArrayList<>(); + + public void delete() { + //agendaPhoto 삭제 + for (Vote vote : voteList) { + vote.delete(); + } + super.delete(); + } +} \ No newline at end of file diff --git a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java index ae1d525e..2457d7c9 100644 --- a/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java +++ b/src/main/java/com/umc/naoman/domain/vote/repository/VoteRepository.java @@ -13,7 +13,4 @@ public interface VoteRepository extends JpaRepository { Boolean existsByProfileIdAndAgendaPhotoId(Long profileId, Long agendaPhotoId); List findByAgendaPhotoId(Long agendaPhotoId); List findByAgendaPhotoIdIn(List agendaPhotoIdList); - @Modifying - @Query("DELETE FROM Vote AS v WHERE v.agendaPhoto.id IN :agendaPhotoIdList") - void deleteByAgendaPhotoIdIn(List agendaPhotoIdList); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java index eaa6d715..f7d0e94f 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteService.java @@ -10,5 +10,4 @@ public interface VoteService { VoteIdList generateVoteList(Long agendaId, GenerateVoteListRequest request, Member member); List getVoteList(Long agendaId, Member member); - void deleteVoteList(Long agendaId, Member member); } diff --git a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java index 5183b46a..2e170174 100644 --- a/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/vote/service/VoteServiceImpl.java @@ -87,20 +87,4 @@ private AgendaPhotoVoteDetails getVoteList(Long agendaPhotoId, Profile viewerPro return voteConverter.toAgendaPhotoVoteDetails(agendaPhotoId, voteInfoList); } - - @Override - public void deleteVoteList(Long agendaId, Member member) { - Agenda agenda = agendaService.findAgenda(agendaId); // 안건 존재 여부 확인 - // 삭제하려는 사람의 프로필 조회 - Profile removerProfile = shareGroupService.findProfile(agenda.getShareGroup().getId(), member.getId()); - if (!Role.CREATOR.equals(removerProfile.getRole())) { - throw new BusinessException(null); - } - - List agendaPhotoIdList = agendaPhotoService.findAgendaPhotoList(agendaId).stream() - .map(agendaPhoto -> agendaPhoto.getId()) - .toList(); - - voteRepository.deleteByAgendaPhotoIdIn(agendaPhotoIdList); - } } From 774aeaf3e1100285947657b651730a89bb3850c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=98=9C=EB=A0=B9?= Date: Sat, 10 Aug 2024 00:16:27 +0900 Subject: [PATCH 18/18] =?UTF-8?q?feat:=20=EC=95=88=EA=B1=B4=20=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../agenda/controller/AgendaController.java | 42 ++++++++++++++++++- .../agenda/converter/AgendaConverter.java | 20 ++++++++- .../domain/agenda/dto/AgendaResponse.java | 12 ++++++ .../agenda/repository/AgendaRepository.java | 4 ++ .../domain/agenda/service/AgendaService.java | 7 +++- .../agenda/service/AgendaServiceImpl.java | 17 ++++++-- .../domain/shareGroup/entity/Profile.java | 12 ++++++ .../domain/shareGroup/entity/ShareGroup.java | 11 ++++- .../global/result/code/AgendaResultCode.java | 4 +- 9 files changed, 117 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java index 070b46e5..7e9fc459 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java +++ b/src/main/java/com/umc/naoman/domain/agenda/controller/AgendaController.java @@ -3,6 +3,8 @@ import com.umc.naoman.domain.agenda.converter.AgendaConverter; import com.umc.naoman.domain.agenda.dto.AgendaRequest; import com.umc.naoman.domain.agenda.dto.AgendaResponse; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.AgendaDetailInfo; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.PagedAgendaDetailInfo; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.agenda.service.AgendaService; import com.umc.naoman.domain.member.entity.Member; @@ -20,14 +22,22 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.web.PageableDefault; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import java.util.List; + +import static com.umc.naoman.global.result.code.AgendaResultCode.GET_AGENDA_LIST; + @RestController @RequestMapping("/agendas") @Tag(name = "04. 안건 관련 API", description = "안건 관련 API입니다.") @@ -56,17 +66,45 @@ public ResultResponse createAgenda(@RequestBody @Vali return ResultResponse.of(AgendaResultCode.CREATE_AGENDA, agendaConverter.toAgendaInfo(agenda)); } + @GetMapping() + @Operation(summary = "특정 공유 그룹의 안건 목록 조회 API", description = "특정 공유 그룹의 안건 목록을 조회하는 API입니다.") + @Parameters(value = { + @Parameter(name = "shareGroupId", description = "특정 안건 id를 입력해 주세요."), + @Parameter(name = "page", description = "조회할 페이지 번호를 입력해주세요.(0번부터)"), + @Parameter(name = "size", description = "한 페이지에 나타낼 안건 개수를 입력해 주세요.") + }) + public ResultResponse getAgendaList(@RequestParam("shareGroupId") Long shareGroupId, + @PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) + @Parameter(hidden = true) Pageable pageable, + @LoginMember Member member) { + PagedAgendaDetailInfo pagedAgendaDetailInfo = agendaService.getAgendaList(shareGroupId, member, pageable); + return ResultResponse.of(GET_AGENDA_LIST, pagedAgendaDetailInfo); + } + + @GetMapping("/{agendaId}") @Operation(summary = "안건 상세 조회 API", description = "agendaId로 안건 상세를 조회하는 API입니다.") @Parameters(value = { @Parameter(name = "agendaId", description = "특정 안건 id를 입력해 주세요.") }) - public ResultResponse getAgendaDetail(@PathVariable(name = "agendaId") Long agendaId, - @LoginMember Member member) { + public ResultResponse getAgendaDetail(@PathVariable(name = "agendaId") Long agendaId, + @LoginMember Member member) { Agenda agenda = agendaService.getAgendaDetailInfo(agendaId, member); return ResultResponse.of(AgendaResultCode.AGENDA_DETAIL, agendaConverter.toAgendaDetailInfo(agenda)); } + + @DeleteMapping("/{agendaId}") + @Operation(summary = "안건 삭제 API", description = "agendaId로 안건 삭제하는 API입니다.") + @Parameters(value = { + @Parameter(name = "agendaId", description = "특정 안건 id를 입력해 주세요.") + }) + public ResultResponse deleteAgenda(@PathVariable(name = "agendaId") Long agendaId, + @LoginMember Member member) { + Agenda agenda = agendaService.deleteAgenda(agendaId); + + return ResultResponse.of(AgendaResultCode.AGENDA_DETAIL, agendaConverter.toAgendaInfo(agenda)); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java index 78a30c98..831bd92e 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java +++ b/src/main/java/com/umc/naoman/domain/agenda/converter/AgendaConverter.java @@ -2,10 +2,12 @@ import com.umc.naoman.domain.agenda.dto.AgendaPhotoResponse; import com.umc.naoman.domain.agenda.dto.AgendaResponse; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.AgendaDetailInfo; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.shareGroup.entity.Profile; import com.umc.naoman.domain.shareGroup.entity.ShareGroup; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.stereotype.Component; import java.util.List; @@ -32,16 +34,30 @@ public Agenda toEntity(Profile profile, String title, ShareGroup shareGroup){ .build(); } - public AgendaResponse.AgendaDetailInfo toAgendaDetailInfo(Agenda agenda) { + public AgendaDetailInfo toAgendaDetailInfo(Agenda agenda) { List agendaPhotoInfoList = agenda.getAgendaPhotoList() .stream() .map(agendaPhotoConverter::toAgendaPhotoInfo) .collect(Collectors.toList()); - return AgendaResponse.AgendaDetailInfo.builder() + return AgendaDetailInfo.builder() .agendaId(agenda.getId()) .title(agenda.getTitle()) .agendaPhotoInfoList(agendaPhotoInfoList) .build(); } + + public AgendaResponse.PagedAgendaDetailInfo toPageAgendaDetailInfo(Page agendaList) { + List agendaDetailInfoList = agendaList.stream() + .map(agenda -> toAgendaDetailInfo(agenda)) + .toList(); + + return AgendaResponse.PagedAgendaDetailInfo.builder() + .agendaDetailInfoList(agendaDetailInfoList) + .totalPages(agendaList.getTotalPages()) + .totalElements(agendaList.getTotalElements()) + .isFirst(agendaList.isFirst()) + .isLast(agendaList.isLast()) + .build(); + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java index 18fbb320..85bce4c2 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java +++ b/src/main/java/com/umc/naoman/domain/agenda/dto/AgendaResponse.java @@ -30,4 +30,16 @@ public static class AgendaDetailInfo { private String title; private List agendaPhotoInfoList; } + + @Getter + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class PagedAgendaDetailInfo { + private List agendaDetailInfoList; + private int totalPages; + private long totalElements; // 해당 조건에 부합하는 요소의 총 개수 + private boolean isFirst; // 첫 페이지 여부 + private boolean isLast; // 마지막 페이지 여부 + } } diff --git a/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaRepository.java b/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaRepository.java index 6e4875ff..55279737 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaRepository.java +++ b/src/main/java/com/umc/naoman/domain/agenda/repository/AgendaRepository.java @@ -1,9 +1,13 @@ package com.umc.naoman.domain.agenda.repository; import com.umc.naoman.domain.agenda.entity.Agenda; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface AgendaRepository extends JpaRepository { + Page findByShareGroupId(Long shareGroupId, Pageable pageable); + } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java index 9ea95622..fa345cb9 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaService.java @@ -1,13 +1,16 @@ package com.umc.naoman.domain.agenda.service; import com.umc.naoman.domain.agenda.dto.AgendaRequest; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.PagedAgendaDetailInfo; import com.umc.naoman.domain.agenda.entity.Agenda; -import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.member.entity.Member; +import org.springframework.data.domain.Pageable; public interface AgendaService { Agenda createAgenda(Member member, AgendaRequest.CreateAgendaRequest request); - Agenda findAgenda(Long agendaId); Agenda getAgendaDetailInfo(Long agendaId, Member member); + PagedAgendaDetailInfo getAgendaList(Long shareGroupId, Member member, Pageable pageable); Agenda deleteAgenda(Long agendaId); + + Agenda findAgenda(Long agendaId); } diff --git a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java index 377dce37..4019aee0 100644 --- a/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java +++ b/src/main/java/com/umc/naoman/domain/agenda/service/AgendaServiceImpl.java @@ -3,6 +3,9 @@ import com.umc.naoman.domain.agenda.converter.AgendaConverter; import com.umc.naoman.domain.agenda.dto.AgendaRequest; import com.umc.naoman.domain.agenda.dto.AgendaRequest.CreateAgendaRequest; +import com.umc.naoman.domain.agenda.dto.AgendaResponse; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.AgendaDetailInfo; +import com.umc.naoman.domain.agenda.dto.AgendaResponse.PagedAgendaDetailInfo; import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.agenda.entity.AgendaPhoto; import com.umc.naoman.domain.agenda.repository.AgendaRepository; @@ -13,22 +16,23 @@ import com.umc.naoman.global.error.BusinessException; import com.umc.naoman.global.error.code.AgendaErrorCode; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service +@Transactional(readOnly = true) @RequiredArgsConstructor public class AgendaServiceImpl implements AgendaService { - private final AgendaRepository agendaRepository; private final ShareGroupService shareGroupService; private final AgendaPhotoService agendaPhotoService; private final AgendaConverter agendaConverter; @Override - @Transactional(readOnly = true) public Agenda findAgenda(Long agendaId) { return agendaRepository.findById(agendaId) .orElseThrow(() -> new BusinessException(AgendaErrorCode.AGENDA_NOT_FOUND_BY_AGENDA_ID)); @@ -47,7 +51,14 @@ public Agenda createAgenda(Member member, CreateAgendaRequest request) { } @Override - @Transactional(readOnly = true) + public PagedAgendaDetailInfo getAgendaList(Long shareGroupId, Member member, Pageable pageable) { + ShareGroup shareGroup = shareGroupService.findShareGroup(shareGroupId); + + Page agendaList = agendaRepository.findByShareGroupId(shareGroupId, pageable); + return agendaConverter.toPageAgendaDetailInfo(agendaList); + } + + @Override public Agenda getAgendaDetailInfo(Long agendaId, Member member) { Agenda agenda = findAgenda(agendaId); diff --git a/src/main/java/com/umc/naoman/domain/shareGroup/entity/Profile.java b/src/main/java/com/umc/naoman/domain/shareGroup/entity/Profile.java index 9053b458..54007531 100644 --- a/src/main/java/com/umc/naoman/domain/shareGroup/entity/Profile.java +++ b/src/main/java/com/umc/naoman/domain/shareGroup/entity/Profile.java @@ -1,6 +1,8 @@ package com.umc.naoman.domain.shareGroup.entity; +import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.domain.member.entity.Member; +import com.umc.naoman.domain.vote.entity.Vote; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -11,6 +13,7 @@ import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; +import jakarta.persistence.OneToMany; import jakarta.persistence.Table; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -20,6 +23,8 @@ import org.hibernate.annotations.SQLRestriction; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Entity @Table(name = "profiles") @@ -50,7 +55,14 @@ public class Profile { @Column(name = "deleted_at") private LocalDateTime deletedAt; + @OneToMany(mappedBy = "profile") + @Builder.Default + private List voteList = new ArrayList<>(); + public void delete() { + for (Vote vote: voteList) { + vote.delete(); + } this.deletedAt = LocalDateTime.now(); } diff --git a/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java b/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java index caacf503..e8339662 100644 --- a/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java +++ b/src/main/java/com/umc/naoman/domain/shareGroup/entity/ShareGroup.java @@ -1,5 +1,6 @@ package com.umc.naoman.domain.shareGroup.entity; +import com.umc.naoman.domain.agenda.entity.Agenda; import com.umc.naoman.global.entity.BaseTimeEntity; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -38,12 +39,18 @@ public class ShareGroup extends BaseTimeEntity { private String inviteCode; @OneToMany(mappedBy = "shareGroup") @Builder.Default - private List profiles = new ArrayList<>(); + private List profileList = new ArrayList<>(); + @OneToMany(mappedBy = "shareGroup") + @Builder.Default + private List agendaList = new ArrayList<>(); public void delete() { - for (Profile profile : profiles) { + for (Profile profile : profileList) { profile.delete(); } + for (Agenda agenda : agendaList) { + agenda.delete(); + } super.delete(); } } diff --git a/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java b/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java index dbc178e3..fd9c09b1 100644 --- a/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java +++ b/src/main/java/com/umc/naoman/global/result/code/AgendaResultCode.java @@ -8,7 +8,9 @@ @RequiredArgsConstructor public enum AgendaResultCode implements ResultCode { CREATE_AGENDA(200, "SA001", "새로운 안건을 성공적으로 생성하였습니다."), - AGENDA_DETAIL(200, "SA002", "상세 안건을 성공적으로 조회했습니다.") + AGENDA_DETAIL(200, "SA002", "상세 안건을 성공적으로 조회했습니다."), + GET_AGENDA_LIST(200, "SA000", "해당 공유 그룹의 안건 목록을 성공적으로 조회했습니다."), + ; private final int status; private final String code;