From 88b897e91e540dc7c6519b8b9351ca87d239b7b9 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 03:39:34 +0900 Subject: [PATCH 01/10] =?UTF-8?q?[feat]=20#25=20=EC=84=A0=EB=AC=BC=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20controller=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 --- .../domain/gift/controller/GiftController.java | 17 ++++++++++++++++- .../gift/dto/request/CreateGiftRequestDto.java | 10 ++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/sopt/sweet/domain/gift/dto/request/CreateGiftRequestDto.java diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java index badc5fc..b6140b1 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java @@ -1,11 +1,26 @@ package org.sopt.sweet.domain.gift.controller; import lombok.RequiredArgsConstructor; +import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.domain.gift.service.GiftService; +import org.sopt.sweet.global.common.SuccessResponse; +import org.sopt.sweet.global.config.auth.UserId; +import org.springframework.http.ResponseEntity; +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; @RequiredArgsConstructor @RequestMapping("/api/gift") @RestController -public class GiftController implements GiftApi{ +public class GiftController implements GiftApi { + + private final GiftService giftService; + + @PostMapping + public ResponseEntity> createNewGift(@UserId Long userId, @RequestBody CreateGiftRequestDto createGiftRequestDto) { + giftService.createNewGift(userId, createGiftRequestDto); + return SuccessResponse.created(null); + } } diff --git a/src/main/java/org/sopt/sweet/domain/gift/dto/request/CreateGiftRequestDto.java b/src/main/java/org/sopt/sweet/domain/gift/dto/request/CreateGiftRequestDto.java new file mode 100644 index 0000000..32e46c8 --- /dev/null +++ b/src/main/java/org/sopt/sweet/domain/gift/dto/request/CreateGiftRequestDto.java @@ -0,0 +1,10 @@ +package org.sopt.sweet.domain.gift.dto.request; + +public record CreateGiftRequestDto( + Long roomId, + String url, + String name, + int cost, + String imageUrl +) { +} From 01216122366c9c51fe75406f9bc2f675f0ff1208 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 03:39:48 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[feat]=20#25=20=EC=84=A0=EB=AC=BC=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20service=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gift/repository/GiftRepository.java | 3 + .../domain/gift/service/GiftService.java | 67 +++++++++++++++++++ .../sopt/sweet/global/error/ErrorCode.java | 2 + 3 files changed, 72 insertions(+) diff --git a/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java b/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java index 001b80f..d292089 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java +++ b/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java @@ -1,7 +1,10 @@ package org.sopt.sweet.domain.gift.repository; import org.sopt.sweet.domain.gift.entity.Gift; +import org.sopt.sweet.domain.member.entity.Member; +import org.sopt.sweet.domain.room.entity.Room; import org.springframework.data.jpa.repository.JpaRepository; public interface GiftRepository extends JpaRepository { + long countByRoomAndMember(Room room, Member member); } diff --git a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java index 7267050..0b6f6bc 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java +++ b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java @@ -1,9 +1,76 @@ package org.sopt.sweet.domain.gift.service; +import lombok.RequiredArgsConstructor; +import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.domain.gift.entity.Gift; +import org.sopt.sweet.domain.gift.repository.GiftRepository; +import org.sopt.sweet.domain.member.entity.Member; +import org.sopt.sweet.domain.member.repository.MemberRepository; +import org.sopt.sweet.domain.room.entity.Room; +import org.sopt.sweet.domain.room.entity.RoomMember; +import org.sopt.sweet.domain.room.repository.RoomMemberRepository; +import org.sopt.sweet.domain.room.repository.RoomRepository; +import org.sopt.sweet.global.error.exception.BusinessException; +import org.sopt.sweet.global.error.exception.EntityNotFoundException; +import org.sopt.sweet.global.error.exception.ForbiddenException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.Optional; + +import static org.sopt.sweet.global.error.ErrorCode.*; + +@RequiredArgsConstructor @Service @Transactional public class GiftService { + private final GiftRepository giftRepository; + private final MemberRepository memberRepository; + private final RoomRepository roomRepository; + private final RoomMemberRepository roomMemberRepository; + private static final int MAX_GIFT_COUNT = 2; + + public void createNewGift(Long memberId, CreateGiftRequestDto createGiftRequestDto) { + Member member = findMemberByIdOrThrow(memberId); + Room room = findRoomByIdOrThrow(createGiftRequestDto.roomId()); + checkRoomMemberNotExists(room, member); + checkGiftCountNotExceeded(room, member); + Gift gift = Gift.builder() + .url(createGiftRequestDto.url()) + .name(createGiftRequestDto.name()) + .cost(createGiftRequestDto.cost()) + .imageUrl(createGiftRequestDto.imageUrl()) + .room(room) + .member(member) + .build(); + giftRepository.save(gift); + } + + private void checkGiftCountNotExceeded(Room room, Member member) { + long giftCount = giftRepository.countByRoomAndMember(room, member); + if (giftCount >= MAX_GIFT_COUNT) { + throw new BusinessException(MEMBER_GIFT_COUNT_EXCEEDED); + } + } + + private boolean isRoomMemberExists(Room room, Member member) { + Optional existingRoomMember = roomMemberRepository.findByRoomAndMember(room, member); + return existingRoomMember.isPresent(); + } + + private void checkRoomMemberNotExists(Room room, Member member) { + if (!isRoomMemberExists(room, member)) { + throw new ForbiddenException(MEMBER_NOT_IN_ROOM); + } + } + + private Member findMemberByIdOrThrow(Long memberId) { + return memberRepository.findById(memberId) + .orElseThrow(() -> new EntityNotFoundException(MEMBER_NOT_FOUND)); + } + + private Room findRoomByIdOrThrow(Long roomId) { + return roomRepository.findById(roomId) + .orElseThrow(() -> new EntityNotFoundException(ROOM_NOT_FOUND)); + } } diff --git a/src/main/java/org/sopt/sweet/global/error/ErrorCode.java b/src/main/java/org/sopt/sweet/global/error/ErrorCode.java index 1a7b73e..96b8741 100644 --- a/src/main/java/org/sopt/sweet/global/error/ErrorCode.java +++ b/src/main/java/org/sopt/sweet/global/error/ErrorCode.java @@ -15,6 +15,7 @@ public enum ErrorCode { NAME_LENGTH_EXCEEDED(HttpStatus.BAD_REQUEST, "이름은 10글자를 초과할 수 없습니다."), MEMBER_NUMBER_EXCEEDED(HttpStatus.BAD_REQUEST, "해당 선물방의 최대 인원을 초과하였습니다."), INVITATION_CLOSED(HttpStatus.BAD_REQUEST, "초대가 마감되었습니다."), + MEMBER_GIFT_COUNT_EXCEEDED(HttpStatus.BAD_REQUEST, "최대 선물 등록 개수를 초과하였습니다."), /** * 401 Unauthorized @@ -32,6 +33,7 @@ public enum ErrorCode { * 403 Forbidden */ FORBIDDEN(HttpStatus.FORBIDDEN, "리소스 접근 권한이 없습니다."), + MEMBER_NOT_IN_ROOM(HttpStatus.FORBIDDEN, "해당 선물 방에 존재하지 않는 멤버입니다."), /** * 404 Not Found From a1d4df3244323a89a095e264bb6ff636e86ec0da Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 03:40:06 +0900 Subject: [PATCH 03/10] =?UTF-8?q?[feat]=20#25=20=EC=84=A0=EB=AC=BC=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20swagger=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sweet/domain/gift/controller/GiftApi.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java index befdb9e..b0c46a2 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java @@ -1,7 +1,40 @@ package org.sopt.sweet.domain.gift.controller; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.global.common.SuccessResponse; +import org.sopt.sweet.global.config.auth.UserId; +import org.springframework.http.ResponseEntity; @Tag(name = "선물", description = "선물 관련 API") public interface GiftApi { + @Operation( + summary = "새로운 선물 등록 API", + responses = { + @ApiResponse( + responseCode = "201", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = SuccessResponse.class) + ) + ) + }, + security = @SecurityRequirement(name = "token") + ) + ResponseEntity> createNewGift( + @Parameter( + description = "authorization token에서 얻은 userId, 임의입력하면 대체됩니다.", + required = true, + example = "12345" + ) @UserId Long userId, + @Valid @RequestBody CreateGiftRequestDto createGiftRequestDto + ); } From db026090c4517981f02926aae9de583b78ec375a Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:18:26 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20swagger=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sweet/domain/gift/controller/GiftApi.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java index b0c46a2..3bce9b9 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java @@ -10,6 +10,7 @@ import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.domain.gift.dto.request.MyGiftsRequestDto; import org.sopt.sweet.global.common.SuccessResponse; import org.sopt.sweet.global.config.auth.UserId; import org.springframework.http.ResponseEntity; @@ -37,4 +38,26 @@ ResponseEntity> createNewGift( ) @UserId Long userId, @Valid @RequestBody CreateGiftRequestDto createGiftRequestDto ); + + @Operation( + summary = "내가 등록한 선물 조회 API", + responses = { + @ApiResponse( + responseCode = "200", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = SuccessResponse.class) + ) + ) + }, + security = @SecurityRequirement(name = "token") + ) + ResponseEntity> getMyGift( + @Parameter( + description = "authorization token에서 얻은 userId, 임의입력하면 대체됩니다.", + required = true, + example = "12345" + ) @UserId Long userId, + @Valid @RequestBody MyGiftsRequestDto myGiftsRequestDto + ); } From 9c9b45fc932c549f74d0109336c67f1c0ae3cb63 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:18:56 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20controller=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/gift/controller/GiftController.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java index b6140b1..97d1898 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java @@ -2,14 +2,13 @@ import lombok.RequiredArgsConstructor; import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.domain.gift.dto.request.MyGiftsRequestDto; +import org.sopt.sweet.domain.gift.dto.response.MyGiftsResponseDto; import org.sopt.sweet.domain.gift.service.GiftService; import org.sopt.sweet.global.common.SuccessResponse; import org.sopt.sweet.global.config.auth.UserId; import org.springframework.http.ResponseEntity; -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; +import org.springframework.web.bind.annotation.*; @RequiredArgsConstructor @RequestMapping("/api/gift") @@ -23,4 +22,10 @@ public ResponseEntity> createNewGift(@UserId Long userId, @Re giftService.createNewGift(userId, createGiftRequestDto); return SuccessResponse.created(null); } + + @GetMapping("/my") + public ResponseEntity> getMyGift(@UserId Long userId, @RequestBody MyGiftsRequestDto myGiftsRequestDto) { + final MyGiftsResponseDto myGiftsResponseDto = giftService.getMyGift(userId, myGiftsRequestDto); + return SuccessResponse.ok(myGiftsResponseDto); + } } From 4fae343267f194c2e9a93fcac54f43edbd553b6a Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:19:08 +0900 Subject: [PATCH 06/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20dto=20=EC=BD=94=EB=93=9C=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 --- .../gift/dto/request/MyGiftsRequestDto.java | 6 ++++++ .../domain/gift/dto/response/MyGiftDto.java | 20 +++++++++++++++++++ .../gift/dto/response/MyGiftsResponseDto.java | 8 ++++++++ 3 files changed, 34 insertions(+) create mode 100644 src/main/java/org/sopt/sweet/domain/gift/dto/request/MyGiftsRequestDto.java create mode 100644 src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftDto.java create mode 100644 src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftsResponseDto.java diff --git a/src/main/java/org/sopt/sweet/domain/gift/dto/request/MyGiftsRequestDto.java b/src/main/java/org/sopt/sweet/domain/gift/dto/request/MyGiftsRequestDto.java new file mode 100644 index 0000000..139493a --- /dev/null +++ b/src/main/java/org/sopt/sweet/domain/gift/dto/request/MyGiftsRequestDto.java @@ -0,0 +1,6 @@ +package org.sopt.sweet.domain.gift.dto.request; + +public record MyGiftsRequestDto( + Long roomId +) { +} diff --git a/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftDto.java b/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftDto.java new file mode 100644 index 0000000..c6d65df --- /dev/null +++ b/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftDto.java @@ -0,0 +1,20 @@ +package org.sopt.sweet.domain.gift.dto.response; + +import lombok.Builder; + +@Builder +public record MyGiftDto( + Long giftId, + String imageUrl, + String name, + int cost +) { + public static MyGiftDto of(Long giftId, String imageUrl, String name, int cost) { + return MyGiftDto.builder() + .giftId(giftId) + .imageUrl(imageUrl) + .name(name) + .cost(cost) + .build(); + } +} diff --git a/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftsResponseDto.java b/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftsResponseDto.java new file mode 100644 index 0000000..979286a --- /dev/null +++ b/src/main/java/org/sopt/sweet/domain/gift/dto/response/MyGiftsResponseDto.java @@ -0,0 +1,8 @@ +package org.sopt.sweet.domain.gift.dto.response; + +import java.util.List; + +public record MyGiftsResponseDto( + List myGiftDtoList +) { +} From 3131dd7e80f063cb69ad304739dbc63ca247440b Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:19:18 +0900 Subject: [PATCH 07/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20service=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gift/repository/GiftRepository.java | 3 ++ .../domain/gift/service/GiftService.java | 29 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java b/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java index d292089..f1d0359 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java +++ b/src/main/java/org/sopt/sweet/domain/gift/repository/GiftRepository.java @@ -5,6 +5,9 @@ import org.sopt.sweet.domain.room.entity.Room; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface GiftRepository extends JpaRepository { long countByRoomAndMember(Room room, Member member); + List findByRoomAndMember(Room room, Member member); } diff --git a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java index 0b6f6bc..a0da7d2 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java +++ b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java @@ -2,6 +2,9 @@ import lombok.RequiredArgsConstructor; import org.sopt.sweet.domain.gift.dto.request.CreateGiftRequestDto; +import org.sopt.sweet.domain.gift.dto.request.MyGiftsRequestDto; +import org.sopt.sweet.domain.gift.dto.response.MyGiftDto; +import org.sopt.sweet.domain.gift.dto.response.MyGiftsResponseDto; import org.sopt.sweet.domain.gift.entity.Gift; import org.sopt.sweet.domain.gift.repository.GiftRepository; import org.sopt.sweet.domain.member.entity.Member; @@ -16,7 +19,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; import static org.sopt.sweet.global.error.ErrorCode.*; @@ -35,7 +40,22 @@ public void createNewGift(Long memberId, CreateGiftRequestDto createGiftRequestD Room room = findRoomByIdOrThrow(createGiftRequestDto.roomId()); checkRoomMemberNotExists(room, member); checkGiftCountNotExceeded(room, member); - Gift gift = Gift.builder() + Gift gift = buildGift(member, room, createGiftRequestDto); + giftRepository.save(gift); + } + + @Transactional(readOnly = true) + public MyGiftsResponseDto getMyGift(Long memberId, MyGiftsRequestDto myGiftsRequestDto) { + Member member = findMemberByIdOrThrow(memberId); + Room room = findRoomByIdOrThrow(myGiftsRequestDto.roomId()); + checkRoomMemberNotExists(room, member); + List gifts = giftRepository.findByRoomAndMember(room, member); + List myGiftsDtoList = mapGiftsToMyGiftDtoList(gifts); + return new MyGiftsResponseDto(myGiftsDtoList); + } + + private Gift buildGift(Member member, Room room, CreateGiftRequestDto createGiftRequestDto) { + return Gift.builder() .url(createGiftRequestDto.url()) .name(createGiftRequestDto.name()) .cost(createGiftRequestDto.cost()) @@ -43,7 +63,12 @@ public void createNewGift(Long memberId, CreateGiftRequestDto createGiftRequestD .room(room) .member(member) .build(); - giftRepository.save(gift); + } + + private List mapGiftsToMyGiftDtoList(List gifts) { + return gifts.stream() + .map(gift -> MyGiftDto.of(gift.getId(), gift.getImageUrl(), gift.getName(), gift.getCost())) + .collect(Collectors.toList()); } private void checkGiftCountNotExceeded(Room room, Member member) { From eb672def8cc47ff472c20024f52a0dd65458fdd3 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:41:55 +0900 Subject: [PATCH 08/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20controller=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/sweet/domain/gift/controller/GiftController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java index 97d1898..d867f88 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftController.java @@ -28,4 +28,10 @@ public ResponseEntity> getMyGift(@UserId Long userId, @Reques final MyGiftsResponseDto myGiftsResponseDto = giftService.getMyGift(userId, myGiftsRequestDto); return SuccessResponse.ok(myGiftsResponseDto); } + + @DeleteMapping ("/my/{giftId}") + public ResponseEntity> deleteMyGift(@UserId Long userId, @PathVariable Long giftId) { + giftService.deleteMyGift(userId, giftId); + return SuccessResponse.ok(null); + } } From c59d46d15df3416ffc5b810755de3c1da7620a27 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:42:07 +0900 Subject: [PATCH 09/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20service=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sweet/domain/gift/service/GiftService.java | 18 ++++++++++++++++++ .../org/sopt/sweet/global/error/ErrorCode.java | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java index a0da7d2..0db24e1 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java +++ b/src/main/java/org/sopt/sweet/domain/gift/service/GiftService.java @@ -54,6 +54,13 @@ public MyGiftsResponseDto getMyGift(Long memberId, MyGiftsRequestDto myGiftsRequ return new MyGiftsResponseDto(myGiftsDtoList); } + public void deleteMyGift(Long memberId, Long giftId){ + Member member = findMemberByIdOrThrow(memberId); + Gift gift = findByIdOrThrow(giftId); + validateMemberGiftOwner(member, gift); + giftRepository.delete(gift); + } + private Gift buildGift(Member member, Room room, CreateGiftRequestDto createGiftRequestDto) { return Gift.builder() .url(createGiftRequestDto.url()) @@ -89,6 +96,12 @@ private void checkRoomMemberNotExists(Room room, Member member) { } } + private void validateMemberGiftOwner(Member member, Gift gift) { + if (!gift.getMember().equals(member)) { + throw new ForbiddenException(MEMBER_NOT_GIFT_OWNER); + } + } + private Member findMemberByIdOrThrow(Long memberId) { return memberRepository.findById(memberId) .orElseThrow(() -> new EntityNotFoundException(MEMBER_NOT_FOUND)); @@ -98,4 +111,9 @@ private Room findRoomByIdOrThrow(Long roomId) { return roomRepository.findById(roomId) .orElseThrow(() -> new EntityNotFoundException(ROOM_NOT_FOUND)); } + + private Gift findByIdOrThrow(Long giftId){ + return giftRepository.findById(giftId) + .orElseThrow(() -> new EntityNotFoundException(GIFT_NOT_FOUND)); + } } diff --git a/src/main/java/org/sopt/sweet/global/error/ErrorCode.java b/src/main/java/org/sopt/sweet/global/error/ErrorCode.java index 96b8741..50b6140 100644 --- a/src/main/java/org/sopt/sweet/global/error/ErrorCode.java +++ b/src/main/java/org/sopt/sweet/global/error/ErrorCode.java @@ -34,6 +34,7 @@ public enum ErrorCode { */ FORBIDDEN(HttpStatus.FORBIDDEN, "리소스 접근 권한이 없습니다."), MEMBER_NOT_IN_ROOM(HttpStatus.FORBIDDEN, "해당 선물 방에 존재하지 않는 멤버입니다."), + MEMBER_NOT_GIFT_OWNER(HttpStatus.FORBIDDEN, "해당 선물을 등록하지 않은 멤버입니다."), /** * 404 Not Found @@ -42,6 +43,7 @@ public enum ErrorCode { OPEN_GRAPH_NOT_FOUND(HttpStatus.NOT_FOUND, "오픈 그래프 정보를 찾을 수 없습니다."), MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 멤버를 찾을 수 없습니다."), ROOM_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 선물방을 찾을 수 없습니다."), + GIFT_NOT_FOUND(HttpStatus.NOT_FOUND, "해당 선물을 찾을 수 없습니다."), /** * 405 Method Not Allowed From 4efe38becc6e351886b7754d6278baa64d966be7 Mon Sep 17 00:00:00 2001 From: ziiyouth Date: Tue, 9 Jan 2024 13:42:18 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[feat]=20#25=20=EB=82=B4=EA=B0=80=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=ED=95=9C=20=EC=84=A0=EB=AC=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B8=B0=EB=8A=A5=20swagger=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sweet/domain/gift/controller/GiftApi.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java index 3bce9b9..53cb4ad 100644 --- a/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java +++ b/src/main/java/org/sopt/sweet/domain/gift/controller/GiftApi.java @@ -14,6 +14,7 @@ import org.sopt.sweet.global.common.SuccessResponse; import org.sopt.sweet.global.config.auth.UserId; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; @Tag(name = "선물", description = "선물 관련 API") public interface GiftApi { @@ -59,5 +60,27 @@ ResponseEntity> getMyGift( example = "12345" ) @UserId Long userId, @Valid @RequestBody MyGiftsRequestDto myGiftsRequestDto - ); + ); + + @Operation( + summary = "내가 등록한 선물 삭제 API", + responses = { + @ApiResponse( + responseCode = "200", + content = @Content( + mediaType = "application/json", + schema = @Schema(implementation = SuccessResponse.class) + ) + ) + }, + security = @SecurityRequirement(name = "token") + ) + ResponseEntity> deleteMyGift( + @Parameter( + description = "authorization token에서 얻은 userId, 임의입력하면 대체됩니다.", + required = true, + example = "12345" + ) @UserId Long userId, + @PathVariable Long giftId + ); }