diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..743e48586 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,69 @@ +name: Deploy Spring Boot Application + +on: + workflow_dispatch: + push: + branches: + - step2-3 # 배포할 브랜치 이름 + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK 21 + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: '21' + + - run: touch ./src/main/resources/application.properties + - run: echo "${{ secrets.APPLICATION_KEY_PROPERTIES }}" > ./src/main/resources/application-key.properties + + - name: Build Spring Boot application + run: ./gradlew build -x test # Gradle build 수행 + + - name: Verify JAR file location + run: ls -l ./build/libs/spring-gift-0.0.1-SNAPSHOT.jar + + - name: Upload JAR file to remote server + uses: appleboy/scp-action@master + with: + host: ${{ secrets.REMOTE_SSH_HOST }} + username: ${{ secrets.REMOTE_SSH_USERNAME }} + key: ${{ secrets.REMOTE_SSH_KEY }} + port: ${{ secrets.REMOTE_SSH_PORT }} + source: "./build/libs/spring-gift-0.0.1-SNAPSHOT.jar" # 빌드된 JAR 파일을 + target: "/home/ubuntu/katecam" # 원격 서버의 디렉토리에 옮김 + + - name: Restart Spring Boot application on remote server + uses: appleboy/ssh-action@master + with: + host: ${{ secrets.REMOTE_SSH_HOST }} + username: ${{ secrets.REMOTE_SSH_USERNAME }} + key: ${{ secrets.REMOTE_SSH_KEY }} + port: ${{ secrets.REMOTE_SSH_PORT }} + script: | + #!/bin/bash + set -e + + # 디렉토리 변경 + cd /home/ubuntu/katecam/build/libs || { echo "Failed to change directory. Exiting."; exit 1; } + + # 디렉토리 내용 확인 + echo "Contents of the directory:" + ls -l + + # 새로운 JAR 파일 이름 변경 + echo "Renaming new JAR file..." + mv spring-gift-0.0.1-SNAPSHOT.jar spring-gift.jar + + # 새로운 JAR 파일 실행 + echo "Starting new JAR file..." + nohup java -jar spring-gift.jar > spring-gift.log 2>&1 & + + # 테스트 + echo "after starting new jar file..." diff --git a/README.md b/README.md index 73a267da1..343ba4688 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# spring-gift-order +# spring-gift-point ## 기능 구현 diff --git a/src/main/java/gift/domain/cartItem/CartItemController.java b/src/main/java/gift/domain/cartItem/CartItemController.java deleted file mode 100644 index 293205bf4..000000000 --- a/src/main/java/gift/domain/cartItem/CartItemController.java +++ /dev/null @@ -1,61 +0,0 @@ -package gift.domain.cartItem; - -import gift.domain.member.dto.LoginInfo; -import gift.domain.cartItem.dto.CartItemDTO; -import gift.global.resolver.Login; -import java.util.List; -import org.springframework.data.domain.Sort; -import org.springframework.data.web.PageableDefault; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; - -@Controller -@RequestMapping("/members/cart") -public class CartItemController { - - private final CartItemService cartItemService; - - public CartItemController(CartItemService cartItemService) { - this.cartItemService = cartItemService; - } - - @GetMapping - public String cartPage( - Model model, - @PageableDefault(page = 0, sort = "id_asc") - @RequestParam(value = "page", defaultValue = "0") int page, - @RequestParam(value = "sort", defaultValue = "id_asc") String sort, - @Login LoginInfo loginInfo) { - int size = 10; // default - Sort sortObj = getSortObject(sort); - - List cartItemDTOS = cartItemService.getProductsInCartByMemberIdAndPageAndSort( - loginInfo.getId(), - page, - size, - sortObj - ); - - model.addAttribute("products", cartItemDTOS); - return "cart"; - } - - private Sort getSortObject(String sort) { - switch (sort) { - case "price_asc": - return Sort.by(Sort.Direction.ASC, "price"); - case "price_desc": - return Sort.by(Sort.Direction.DESC, "price"); - case "name_asc": - return Sort.by(Sort.Direction.ASC, "name"); - case "name_desc": - return Sort.by(Sort.Direction.DESC, "name"); - default: - return Sort.by(Sort.Direction.ASC, "id"); - } - } -} - diff --git a/src/main/java/gift/domain/cartItem/CartItemRestController.java b/src/main/java/gift/domain/cartItem/CartItemRestController.java deleted file mode 100644 index d1206ede1..000000000 --- a/src/main/java/gift/domain/cartItem/CartItemRestController.java +++ /dev/null @@ -1,122 +0,0 @@ -package gift.domain.cartItem; - -import gift.domain.cartItem.dto.CartItemDTO; -import gift.domain.member.dto.LoginInfo; -import gift.global.resolver.Login; -import gift.global.response.ResponseMaker; -import gift.global.response.ResultResponseDto; -import gift.global.response.SimpleResultResponseDto; -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.tags.Tag; -import java.util.List; -import org.springframework.data.domain.Sort; -import org.springframework.http.HttpStatus; -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.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -@RequestMapping("/api/members/cart") -@Tag(name = "CartItem", description = "CartItem API") -public class CartItemRestController { - - private final CartItemService cartItemService; - - public CartItemRestController(CartItemService cartItemService) { - this.cartItemService = cartItemService; - } - - - /** - * 장바구니에 상품 담기 - */ - @PostMapping("/{productId}") - @Operation(summary = "장바구니에 상품 담기") - public ResponseEntity> addCartItem( - @Parameter(description = "상품 ID") @PathVariable("productId") Long productId, - @Parameter(description = "로그인 유저 정보") @Login LoginInfo loginInfo - ) { - int currentCount = cartItemService.addCartItem(loginInfo.getId(), productId); - - return ResponseMaker.createResponse(HttpStatus.OK, - "상품이 장바구니에 추가되었습니다. 총 개수: " + currentCount, currentCount); - } - - /** - * 장바구니 조회 - 페이징(매개변수별) - */ - @GetMapping - @Operation(summary = "장바구니 조회 - 페이징") - public ResponseEntity>> getProductsInCartByUserIdAndPageAndSort( - @Parameter(description = "페이지 번호") @RequestParam(value = "page", defaultValue = "0") int page, - @Parameter(description = "정렬 기준") @RequestParam(value = "sort", defaultValue = "id_asc") String sort, - @Parameter(description = "로그인 유저 정보") @Login LoginInfo loginInfo - ) { - int size = 10; // default - Sort sortObj = getSortObject(sort); - - List cartItemDTOS = cartItemService.getProductsInCartByMemberIdAndPageAndSort( - loginInfo.getId(), - page, - size, - sortObj - ); - - return ResponseMaker.createResponse(HttpStatus.OK, "장바구니 조회에 성공했습니다.", cartItemDTOS); - } - - /** - * 장바구니 상품 삭제 - */ - @DeleteMapping("/{cartItemId}") - @Operation(summary = "장바구니 상품 삭제") - public ResponseEntity deleteCartItem( - @Parameter(description = "장바구니 상품(CartItem) ID") @PathVariable("cartItemId") Long cartItemId, - @Parameter(description = "로그인 유저 정보") @Login LoginInfo loginInfo - ) { - cartItemService.deleteCartItem(cartItemId); - - return ResponseMaker.createSimpleResponse(HttpStatus.OK, "장바구니에서 상품이 삭제되었습니다."); - } - - /** - * 장바구니 상품 수량 변경 - */ - // TODO cartItem 에 userId, productId, + 상품 정보까지 담는걸로 - // 안그러면 productId 로 다시 상품 정보를 불러와야 함..페이징할때도 cartItem 에서 바로 할 수 있으니 나을 것 같다 - @PutMapping("/{cartItemId}") - @Operation(summary = "장바구니 상품 수량 변경") - public ResponseEntity updateCartItem( - @Parameter(description = "장바구니 상품(CartItem) ID") @PathVariable("cartItemId") Long cartItemId, - @Parameter(description = "변경할 상품 수량") @RequestParam("count") int count, - @Parameter(description = "로그인 유저 정보") @Login LoginInfo loginInfo - ) { - int modifiedCount = cartItemService.updateCartItem(cartItemId, count); - - return ResponseMaker.createSimpleResponse(HttpStatus.OK, - "해당 상품의 수량이 변경되었습니다. 총 개수: " + modifiedCount + "개"); - } - - // TODO 페이징 기준을 cartItem 에 맞춰서 수정해야함.. 간단한건 생성날짜? <- 추가 속성 필요 - private Sort getSortObject(String sort) { - switch (sort) { - case "price_asc": - return Sort.by(Sort.Direction.ASC, "price"); - case "price_desc": - return Sort.by(Sort.Direction.DESC, "price"); - case "name_asc": - return Sort.by(Sort.Direction.ASC, "name"); - case "name_desc": - return Sort.by(Sort.Direction.DESC, "name"); - default: - return Sort.by(Sort.Direction.ASC, "id"); - } - } -} diff --git a/src/main/java/gift/domain/cartItem/CartItemService.java b/src/main/java/gift/domain/cartItem/CartItemService.java deleted file mode 100644 index 19300cbd9..000000000 --- a/src/main/java/gift/domain/cartItem/CartItemService.java +++ /dev/null @@ -1,110 +0,0 @@ -package gift.domain.cartItem; - -import gift.domain.member.Member; -import gift.domain.cartItem.dto.CartItemDTO; -import gift.domain.option.JpaOptionRepository; -import gift.domain.option.Option; -import gift.domain.product.JpaProductRepository; -import gift.domain.product.Product; -import gift.domain.member.JpaMemberRepository; -import gift.global.exception.cartItem.CartItemNotFoundException; -import gift.global.exception.product.ProductNotFoundException; -import gift.global.exception.user.UserNotFoundException; -import java.util.List; -import java.util.Optional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -@Service -public class CartItemService { - - private final JpaProductRepository productRepository; - private final JpaCartItemRepository cartItemRepository; - private final JpaMemberRepository userRepository; - private final JpaOptionRepository optionRepository; - - public CartItemService( - JpaProductRepository jpaProductRepository, - JpaCartItemRepository jpaCartItemRepository, - JpaMemberRepository jpaMemberRepository, - JpaOptionRepository jpaOptionRepository - ) { - this.userRepository = jpaMemberRepository; - this.cartItemRepository = jpaCartItemRepository; - this.productRepository = jpaProductRepository; - this.optionRepository = jpaOptionRepository; - } - - /** - * 장바구니에 상품 ID 추가 - */ - @Transactional - public int addCartItem(Long memberId, Long productId) { - Member member = userRepository.findById(memberId) - .orElseThrow(() -> new UserNotFoundException(memberId)); - Product product = productRepository.findById(productId) - .orElseThrow(() -> new ProductNotFoundException(productId)); - - // 기존에 존재하면 update - Optional findCartItem = cartItemRepository.findByMemberIdAndProductId(memberId, - productId); - if (findCartItem.isPresent()) { - return findCartItem.get().addOneMore(); - } - // 기존에 없었으면 new - CartItem newCartItem = new CartItem(member, product); - cartItemRepository.save(newCartItem); - return newCartItem.getCount(); - } - - /** - * 장바구니 상품 조회 - 페이징(매개변수별) - */ - public List getProductsInCartByMemberIdAndPageAndSort(Long memberId, int page, - int size, Sort sort) { - PageRequest pageRequest = PageRequest.of(page, size, sort); - - Page cartItemsPage = cartItemRepository.findAllByMemberId(memberId, - pageRequest); - - List cartItemDTOS = cartItemsPage.getContent().stream() - .map(cartItem -> { - return new CartItemDTO(cartItem); - }) - .toList(); - - // 새 Page 객체 생성 - return cartItemDTOS; - } - - /** - * 장바구니 상품 삭제` - */ - public void deleteCartItem(Long cartItemId) { - cartItemRepository.deleteById(cartItemId); - } - - /** - * 장바구니 상품 수량 수정 - */ - @Transactional - public int updateCartItem(Long cartItemId, int count) { - CartItem findCartItem = cartItemRepository.findById(cartItemId) - .orElseThrow(() -> new CartItemNotFoundException(cartItemId)); - - findCartItem.updateCount(count); // 수량 수정 - return count; - } - - /** - * 장바구니에 해당 옵션의 상품이 존재하면 삭제 - */ - public void deleteCartItemIfExists(Long memberId, Long optionId) { - Option option = optionRepository.findById(optionId).get(); - cartItemRepository.findByMemberIdAndProductId(memberId, option.getProduct().getId()) - .ifPresent(cartItemRepository::delete); - } -} diff --git a/src/main/java/gift/domain/cartItem/JpaCartItemRepository.java b/src/main/java/gift/domain/cartItem/JpaCartItemRepository.java deleted file mode 100644 index 622eebcf5..000000000 --- a/src/main/java/gift/domain/cartItem/JpaCartItemRepository.java +++ /dev/null @@ -1,25 +0,0 @@ -package gift.domain.cartItem; - -import gift.domain.member.Member; -import java.util.List; -import java.util.Optional; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -@Repository -public interface JpaCartItemRepository extends JpaRepository { - - List findAllByMemberId(Long memberId); - - void deleteById(Long id); - - List findAllByMember(Member member); - - Optional findByMemberIdAndProductId(Long memberId, Long productId); - - // paging - Page findAllByMemberId(Long memberId, PageRequest pageRequest); - -} diff --git a/src/main/java/gift/domain/cartItem/dto/CartItemDTO.java b/src/main/java/gift/domain/cartItem/dto/CartItemDTO.java deleted file mode 100644 index 26bcba9e8..000000000 --- a/src/main/java/gift/domain/cartItem/dto/CartItemDTO.java +++ /dev/null @@ -1,24 +0,0 @@ -package gift.domain.cartItem.dto; - -import gift.domain.cartItem.CartItem; - -public record CartItemDTO( - Long id, - Long productId, - String name, - Integer price, - String imageUrl, - Integer count -) { - - public CartItemDTO(CartItem cartItem) { - this( - cartItem.getId(), - cartItem.getProduct().getId(), - cartItem.getProduct().getName(), - cartItem.getProduct().getPrice(), - cartItem.getProduct().getImageUrl(), - cartItem.getCount() - ); - } -} diff --git a/src/main/java/gift/domain/category/Category.java b/src/main/java/gift/domain/category/Category.java index 2f13a4130..2d6a1d838 100644 --- a/src/main/java/gift/domain/category/Category.java +++ b/src/main/java/gift/domain/category/Category.java @@ -19,12 +19,18 @@ public class Category { private String description; + private String color; + + private String imageUrl; + protected Category() { } - public Category(String name, String description) { + public Category(String name, String description, String color, String imageUrl) { this.name = name; this.description = description; + this.color = color; + this.imageUrl = imageUrl; } public Category(long id, String name, String description) { @@ -41,13 +47,24 @@ public String getName() { return name; } + public String getColor() { + return color; + } + + public String getImageUrl() { + return imageUrl; + } + public String getDescription() { return description; } - public void update(String name, String description) { + + public void update(String name, String description, String color, String imageUrl) { this.name = name; this.description = description; + this.color = color; + this.imageUrl = imageUrl; } @Override diff --git a/src/main/java/gift/domain/category/CategoryDTO.java b/src/main/java/gift/domain/category/CategoryDTO.java deleted file mode 100644 index 1aa597f47..000000000 --- a/src/main/java/gift/domain/category/CategoryDTO.java +++ /dev/null @@ -1,10 +0,0 @@ -package gift.domain.category; - -import jakarta.validation.constraints.NotBlank; - -public record CategoryDTO( - @NotBlank String name, - @NotBlank String description -) { - -} \ No newline at end of file diff --git a/src/main/java/gift/domain/category/CategoryRestController.java b/src/main/java/gift/domain/category/CategoryRestController.java index d6356745c..354822937 100644 --- a/src/main/java/gift/domain/category/CategoryRestController.java +++ b/src/main/java/gift/domain/category/CategoryRestController.java @@ -1,5 +1,6 @@ package gift.domain.category; +import gift.domain.category.dto.request.CategoryRequest; import gift.global.response.ResponseMaker; import gift.global.response.ResultResponseDto; import gift.global.response.SimpleResultResponseDto; @@ -31,36 +32,36 @@ public CategoryRestController(CategoryService categoryService) { } @GetMapping - @Operation(summary = "모든 카테고리 조회") - public ResponseEntity>> getCategories() { + @Operation(summary = "카테고리 목록 조회") + public ResponseEntity> getCategories() { List categories = categoryService.getCategories(); - return ResponseMaker.createResponse(HttpStatus.OK, "전체 카테코리 목록 조회 성공", categories); + return ResponseEntity.ok(categories); } @PostMapping - @Operation(summary = "카테고리 추가") - public ResponseEntity createCategory( - @Valid @RequestBody CategoryDTO categoryDTO) { - categoryService.createCategory(categoryDTO); - return ResponseMaker.createSimpleResponse(HttpStatus.OK, "카테고리 추가 성공"); + @Operation(summary = "카테고리 생성") + public ResponseEntity createCategories( + @Valid @RequestBody List categoryRequests) { + categoryService.createCategories(categoryRequests); + return ResponseEntity.ok().build(); } - @DeleteMapping("{id}") + @DeleteMapping("{categoryId}") @Operation(summary = "카테고리 삭제") - public ResponseEntity deleteCategory( - @Parameter(description = "카테고리 ID") @PathVariable("id") Long id + public ResponseEntity deleteCategory( + @Parameter(description = "카테고리 ID") @PathVariable("categoryId") Long id ) { categoryService.deleteCategory(id); - return ResponseMaker.createSimpleResponse(HttpStatus.OK, "카테고리 삭제 성공"); + return ResponseEntity.ok().build(); } - @PutMapping("{id}") + @PutMapping("{categoryId}") @Operation(summary = "카테고리 수정") - public ResponseEntity updateCategory( - @Parameter(description = "카테고리 ID") @PathVariable("id") Long id, - @Valid @RequestBody CategoryDTO categoryDTO + public ResponseEntity updateCategory( + @Parameter(description = "카테고리 ID") @PathVariable("categoryId") Long id, + @Valid @RequestBody CategoryRequest categoryRequest ) { - categoryService.updateCategory(id, categoryDTO); - return ResponseMaker.createSimpleResponse(HttpStatus.OK, "카테고리 수정 성공"); + categoryService.updateCategory(id, categoryRequest); + return ResponseEntity.ok().build(); } } diff --git a/src/main/java/gift/domain/category/CategoryService.java b/src/main/java/gift/domain/category/CategoryService.java index 4d6b15283..404714b78 100644 --- a/src/main/java/gift/domain/category/CategoryService.java +++ b/src/main/java/gift/domain/category/CategoryService.java @@ -1,5 +1,6 @@ package gift.domain.category; +import gift.domain.category.dto.request.CategoryRequest; import gift.global.exception.category.CategoryDuplicateException; import gift.global.exception.category.CategoryNotFoundException; import java.util.List; @@ -11,7 +12,7 @@ public class CategoryService { private final JpaCategoryRepository categoryRepository; - public CategoryService(gift.domain.category.JpaCategoryRepository categoryRepository) { + public CategoryService(JpaCategoryRepository categoryRepository) { this.categoryRepository = categoryRepository; } @@ -19,13 +20,13 @@ public List getCategories() { return categoryRepository.findAll(); } - public void createCategory(CategoryDTO categoryDTO) { - if (categoryRepository.existsByName(categoryDTO.name())) { - throw new CategoryDuplicateException(categoryDTO.name()); + public void createCategories(List categoryRequests) { + for (CategoryRequest categoryRequest : categoryRequests) { + if (categoryRepository.existsByName(categoryRequest.name())) { + throw new CategoryDuplicateException(categoryRequest.name()); + } + categoryRepository.save(categoryRequest.toCategory()); } - - Category category = new Category(categoryDTO.name(), categoryDTO.description()); - categoryRepository.save(category); } public void deleteCategory(Long id) { @@ -37,16 +38,20 @@ public void deleteCategory(Long id) { } @Transactional - public void updateCategory(Long id, CategoryDTO categoryDTO) { + public void updateCategory(Long id, CategoryRequest categoryRequest) { Category findCategory = categoryRepository.findById(id) .orElseThrow(() -> new CategoryNotFoundException(id)); // 이름 중복 검사, 중복되면서 id 가 자신이 아닐 때 - if (hasDuplicateName(id, categoryDTO.name())) { - throw new CategoryDuplicateException(categoryDTO.name()); + if (hasDuplicateName(id, categoryRequest.name())) { + throw new CategoryDuplicateException(categoryRequest.name()); } - findCategory.update(categoryDTO.name(), categoryDTO.description()); + findCategory.update(categoryRequest.name(), + categoryRequest.description(), + categoryRequest.color(), + categoryRequest.imageUrl() + ); } /** diff --git a/src/main/java/gift/domain/category/dto/request/CategoryRequest.java b/src/main/java/gift/domain/category/dto/request/CategoryRequest.java new file mode 100644 index 000000000..e05949d8f --- /dev/null +++ b/src/main/java/gift/domain/category/dto/request/CategoryRequest.java @@ -0,0 +1,25 @@ +package gift.domain.category.dto.request; + +import gift.domain.category.Category; +import jakarta.validation.constraints.NotBlank; +import org.hibernate.validator.constraints.URL; + +public record CategoryRequest( + @NotBlank + String name, + + @NotBlank + String description, + + @NotBlank + String color, + + @NotBlank + @URL + String imageUrl +) { + + public Category toCategory() { + return new Category(this.name, this.description, this.color, this.imageUrl); + } +} diff --git a/src/main/java/gift/domain/category/dto/response/CategoryResponse.java b/src/main/java/gift/domain/category/dto/response/CategoryResponse.java new file mode 100644 index 000000000..172bf1b69 --- /dev/null +++ b/src/main/java/gift/domain/category/dto/response/CategoryResponse.java @@ -0,0 +1,5 @@ +package gift.domain.category.dto.response; + +public class CategoryResponse { + +} diff --git a/src/main/java/gift/domain/member/Member.java b/src/main/java/gift/domain/member/Member.java index 45059d0ce..75a74dd7c 100644 --- a/src/main/java/gift/domain/member/Member.java +++ b/src/main/java/gift/domain/member/Member.java @@ -28,6 +28,7 @@ public class Member extends BaseTimeEntity { @Enumerated(EnumType.STRING) private MemberRole role; + private int point; private String accessToken; private String refreshToken; @@ -60,6 +61,10 @@ public String getPassword() { return password; } + public MemberRole getRole() { return role; } + + public int getPoint() { return point; } + public String getAccessToken() { return accessToken; } @@ -100,4 +105,12 @@ public void updateKaKaoToken(KaKaoToken kaKaoToken) { this.accessToken = kaKaoToken.accessToken(); this.refreshToken = kaKaoToken.refreshToken(); } + + public void chargePoint(int point) { + this.point += point; + } + + public void usePoint(Integer point) { + this.point -= point; + } } diff --git a/src/main/java/gift/domain/member/MemberRestController.java b/src/main/java/gift/domain/member/MemberRestController.java index a051e708b..5025bda92 100644 --- a/src/main/java/gift/domain/member/MemberRestController.java +++ b/src/main/java/gift/domain/member/MemberRestController.java @@ -1,12 +1,10 @@ package gift.domain.member; -import gift.domain.member.dto.MemberDTO; -import gift.global.response.ResponseMaker; -import gift.global.response.SimpleResultResponseDto; +import gift.domain.member.dto.request.MemberRequest; +import gift.domain.member.dto.response.MemberResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -29,10 +27,10 @@ public MemberRestController(MemberService memberService) { */ @PostMapping("/register") @Operation(summary = "회원가입") - public ResponseEntity join(@Valid @RequestBody MemberDTO memberDTO) { - memberService.join(memberDTO); + public ResponseEntity join(@Valid @RequestBody MemberRequest memberRequest) { + MemberResponse memberResponse = memberService.join(memberRequest); - return ResponseMaker.createSimpleResponse(HttpStatus.OK, "회원 가입에 성공했습니다"); + return ResponseEntity.ok(memberResponse); } /** @@ -40,10 +38,10 @@ public ResponseEntity join(@Valid @RequestBody MemberDT */ @PostMapping("/login") @Operation(summary = "로그인을 한 후 JWT 토큰을 발급받는다.") - public ResponseEntity login(@Valid @RequestBody MemberDTO memberDTO) { - String jwt = memberService.login(memberDTO); + public ResponseEntity login(@Valid @RequestBody MemberRequest memberRequest) { + MemberResponse memberResponse = memberService.login(memberRequest); - return ResponseMaker.createSimpleResponseWithJwtOnHeader(HttpStatus.OK, "로그인에 성공했습니다", jwt); + return ResponseEntity.ok(memberResponse); } } diff --git a/src/main/java/gift/domain/member/MemberService.java b/src/main/java/gift/domain/member/MemberService.java index a3296a9b2..17900dc88 100644 --- a/src/main/java/gift/domain/member/MemberService.java +++ b/src/main/java/gift/domain/member/MemberService.java @@ -1,6 +1,7 @@ package gift.domain.member; -import gift.domain.member.dto.MemberDTO; +import gift.domain.member.dto.request.MemberRequest; +import gift.domain.member.dto.response.MemberResponse; import gift.global.exception.BusinessException; import gift.global.exception.ErrorCode; import gift.global.exception.user.UserDuplicateException; @@ -19,26 +20,27 @@ public MemberService(JpaMemberRepository jpaMemberRepository) { /** * 회원 가입 */ - public void join(MemberDTO memberDTO) { - if (memberRepository.existsByEmail(memberDTO.getEmail())) { - throw new UserDuplicateException(memberDTO.getEmail()); + public MemberResponse join(MemberRequest memberRequest) { + if (memberRepository.existsByEmail(memberRequest.email())) { + throw new UserDuplicateException(memberRequest.email()); } - Member member = memberDTO.toMember(); - memberRepository.save(member); - } + Member member = memberRequest.toMember(); + Member savedMember = memberRepository.save(member); + String jwt = JwtProvider.generateToken(savedMember); + return new MemberResponse(member.getEmail(), jwt); + } - /** - * 로그인, 성공 시 JWT 반환 - */ - public String login(MemberDTO memberDTO) { - Member member = memberRepository.findByEmailAndPassword(memberDTO.getEmail(), memberDTO.getPassword()) - .orElseThrow(() -> new BusinessException(ErrorCode.BAD_REQUEST, "입력 정보가 올바르지 않습니다.")); - // jwt 토큰 생성 - String jwt = JwtProvider.generateToken(member); + /** + * 로그인, 성공 시 JWT 반환 + */ + public MemberResponse login(MemberRequest memberRequest) { + Member member = memberRepository.findByEmailAndPassword(memberRequest.email(), memberRequest.password()) + .orElseThrow(() -> new BusinessException(ErrorCode.BAD_REQUEST, "입력 정보가 올바르지 않습니다.")); - return jwt; - } + String jwt = JwtProvider.generateToken(member); + return new MemberResponse(member.getEmail(), jwt); + } } diff --git a/src/main/java/gift/domain/member/dto/MemberDTO.java b/src/main/java/gift/domain/member/dto/MemberDTO.java deleted file mode 100644 index 9052dac29..000000000 --- a/src/main/java/gift/domain/member/dto/MemberDTO.java +++ /dev/null @@ -1,41 +0,0 @@ -package gift.domain.member.dto; - -import gift.domain.member.Member; -import jakarta.validation.constraints.Email; -import jakarta.validation.constraints.NotBlank; - -public class MemberDTO { - - @Email - private String email; - @NotBlank - private String password; - - public MemberDTO(String email, String password) { - this.email = email; - this.password = password; - } - - public MemberDTO() { - } - - public String getEmail() { - return email; - } - - public String getPassword() { - return password; - } - - public Member toMember() { - return new Member(this.email, this.password); // dto to entity - } - - @Override - public String toString() { - return "MemberDTO{" + - "email='" + email + '\'' + - ", password='" + password + '\'' + - '}'; - } -} diff --git a/src/main/java/gift/domain/member/dto/request/MemberRequest.java b/src/main/java/gift/domain/member/dto/request/MemberRequest.java new file mode 100644 index 000000000..efe586b91 --- /dev/null +++ b/src/main/java/gift/domain/member/dto/request/MemberRequest.java @@ -0,0 +1,18 @@ +package gift.domain.member.dto.request; + +import gift.domain.member.Member; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; + +public record MemberRequest ( + @Email + String email, + + @NotBlank + String password +) +{ + public Member toMember() { + return new Member(this.email, this.password); // dto to entity + } +} diff --git a/src/main/java/gift/domain/member/dto/response/MemberResponse.java b/src/main/java/gift/domain/member/dto/response/MemberResponse.java new file mode 100644 index 000000000..e4587daae --- /dev/null +++ b/src/main/java/gift/domain/member/dto/response/MemberResponse.java @@ -0,0 +1,8 @@ +package gift.domain.member.dto.response; + +public record MemberResponse( + String email, + String accessToken +) { + +} diff --git a/src/main/java/gift/domain/member/kakao/KaKaoController.java b/src/main/java/gift/domain/member/kakao/KaKaoController.java index c4c3d5bf8..d98a45aad 100644 --- a/src/main/java/gift/domain/member/kakao/KaKaoController.java +++ b/src/main/java/gift/domain/member/kakao/KaKaoController.java @@ -1,13 +1,13 @@ package gift.domain.member.kakao; import gift.domain.member.Member; +import gift.domain.member.dto.response.MemberResponse; import gift.global.jwt.JwtProvider; import gift.global.response.ResponseMaker; import gift.global.response.SimpleResultResponseDto; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -16,7 +16,7 @@ import org.springframework.web.servlet.view.RedirectView; @RestController -@RequestMapping("/api/members/oauth") +@RequestMapping @Tag(name = "KaKao", description = "KaKao API") public class KaKaoController { @@ -27,9 +27,9 @@ public KaKaoController(KaKaoService kaKaoService) { } /** - * 카카오 로그인 페이지로 이동 + * 카카오 로그인 페이지 뷰 제공 */ - @GetMapping("/kakao/login") + @GetMapping("/api/oauth/kakao") @Operation(summary = "카카오 로그인 페이지로 이동") public RedirectView LoginPage() { return new RedirectView(kaKaoService.buildLoginPageUrl()); @@ -38,15 +38,17 @@ public RedirectView LoginPage() { /** * 카카오 로그인 인가코드로 JWT 발급 */ - @GetMapping("/kakao") + @GetMapping @Operation(summary = "카카오 로그인 인가코드로 JWT 발급") - public ResponseEntity JwtToken( + public ResponseEntity getAuth( @Parameter(description = "카카오 로그인 인가코드") @RequestParam(value = "code") String authorizedCode ) { KaKaoToken kaKaoToken = kaKaoService.getKaKaoToken(authorizedCode); Member findMember = kaKaoService.loginOrRegister(kaKaoToken); String jwt = JwtProvider.generateToken(findMember); - return ResponseMaker.createSimpleResponseWithJwtOnHeader(HttpStatus.OK, "카카오 로그인 성공", jwt); + MemberResponse memberResponse = new MemberResponse(findMember.getEmail(), jwt); + System.out.println("memberResponse = " + memberResponse); + return ResponseEntity.ok(memberResponse); } } diff --git a/src/main/java/gift/domain/option/Option.java b/src/main/java/gift/domain/option/Option.java index b75a6fa22..1c59c7e7b 100644 --- a/src/main/java/gift/domain/option/Option.java +++ b/src/main/java/gift/domain/option/Option.java @@ -1,5 +1,6 @@ package gift.domain.option; +import gift.domain.option.dto.response.OptionResponse; import gift.domain.product.Product; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -28,7 +29,7 @@ public class Option { @JoinColumn(name = "product_id") private Product product; - public Option() { + protected Option() { } public Option(String name, Long quantity, Product product) { @@ -98,4 +99,8 @@ public int hashCode() { public void decrease(Long quantity) { this.quantity -= quantity; } + + public OptionResponse toOptionResponse() { + return new OptionResponse(this.id, this.name, this.quantity); + } } diff --git a/src/main/java/gift/domain/option/OptionRestController.java b/src/main/java/gift/domain/option/OptionRestController.java index 75330881d..b61694f89 100644 --- a/src/main/java/gift/domain/option/OptionRestController.java +++ b/src/main/java/gift/domain/option/OptionRestController.java @@ -1,17 +1,14 @@ package gift.domain.option; -import gift.domain.option.dto.OptionRequestDTO; -import gift.domain.option.dto.OptionResponseDTO; -import gift.global.response.ResponseMaker; -import gift.global.response.ResultResponseDto; -import gift.global.response.SimpleResultResponseDto; +import gift.domain.option.dto.request.OptionRequest; +import gift.domain.option.dto.response.OptionResponse; 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 java.util.List; -import org.springframework.http.HttpStatus; 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; @@ -21,7 +18,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/api") +@RequestMapping("/api/products") @Tag(name = "Option", description = "Option API") public class OptionRestController { @@ -31,57 +28,55 @@ public OptionRestController(OptionService optionService) { this.optionService = optionService; } - /** - * 모든 옵션 목록 조회 - */ - @GetMapping("/options") - @Operation(summary = "모든 옵션 조회") - public ResponseEntity>> getOptions() { - List