Skip to content

Commit

Permalink
Merge pull request #30 from kea-dpang/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
oo-ni authored Jan 31, 2024
2 parents 23b12b2 + c603b4f commit e77564d
Show file tree
Hide file tree
Showing 13 changed files with 246 additions and 93 deletions.
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ ext {
dependencies {
// Spring
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/kea/dpang/item/ItemServerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableFeignClients
public class ItemServerApplication {

public static void main(String[] args) {
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/kea/dpang/item/base/ErrorResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package kea.dpang.item.base;

import lombok.Getter;
import lombok.Setter;

import java.time.LocalDateTime;

/**
* BaseErrorResponse는 API 에러 응답의 기본 형식을 정의하는 클래스
* 모든 API 에러 응답은 이 클래스를 상속받아야 하며, BaseResponse의 속성에 추가로 에러에 대한 상세 정보를 포함한다.
*/
@Getter
@Setter
public class ErrorResponse extends BaseResponse {

private String error;
private String path;
private LocalDateTime timestamp;

/**
* @param status HTTP 상태 코드
* @param message 에러 메시지
* @param error 발생한 에러의 이름
* @param path 에러가 발생한 요청 경로
* @param timestamp 에러 발생 시간
*/
public ErrorResponse(int status, String message, String error, String path, LocalDateTime timestamp) {
super(status, message);
this.error = error;
this.path = path;
this.timestamp = timestamp;
}
}
27 changes: 27 additions & 0 deletions src/main/java/kea/dpang/item/base/SuccessResponse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package kea.dpang.item.base;


import lombok.Getter;
import lombok.Setter;

/**
* SuccessResponse는 API 성공 응답의 기본 형식을 정의하는 클래스
* 모든 API 성공 응답은 이 클래스를 상속받아야 하며, BaseResponse의 속성에 추가로 성공에 대한 데이터를 포함한다.
*/
@Getter
@Setter
public class SuccessResponse<T> extends BaseResponse {

private T data;

/**
* @param status HTTP 상태 코드
* @param message 성공 메시지
* @param data 성공 데이터
*/
public SuccessResponse(int status, String message, T data) {
super(status, message);
this.data = data;
}
}

130 changes: 84 additions & 46 deletions src/main/java/kea/dpang/item/controller/ItemController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import kea.dpang.item.base.BaseResponse;
import io.swagger.v3.oas.annotations.tags.Tag;

import kea.dpang.item.base.*;
import kea.dpang.item.dto.*;
import kea.dpang.item.service.ItemServiceImpl;

import kea.dpang.item.service.ReviewServiceImpl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

Expand All @@ -19,6 +21,7 @@

@RestController
@RequiredArgsConstructor
@Tag(name="Item API", description = "상품 관련 API 입니다.")
@RequestMapping("/api/items")
@Slf4j
public class ItemController {
Expand All @@ -29,105 +32,140 @@ public class ItemController {
@PostMapping
@Operation(summary = "상품 등록", description = "상품 정보를 시스템에 추가합니다.")
public ResponseEntity<BaseResponse> createItem(@RequestBody ItemCreateDto itemCreateDto) {
itemService.createItem(itemCreateDto);

ItemResponseDto item = itemService.createItem(itemCreateDto);
log.info("새로운 상품 등록 완료. 상품 ID: {}", item.getItemId());
return new ResponseEntity<>(
new BaseResponse(HttpStatus.CREATED.value(), "상품이 등록되었습니다."),
HttpStatus.CREATED
);
}

@GetMapping("/cards")
@GetMapping("/cardlist")
@Operation(summary = "상품 카드 리스트 조회", description = "페이지 정보에 따라 상품 카드 리스트를 조회합니다.")
public ResponseEntity<List<ItemCardDto>> getItemCard(Pageable pageable) {
public ResponseEntity<SuccessResponse<List<ItemCardDto>>> getItemCard(Pageable pageable) {
List<ItemCardDto> items = itemService.getItemCard(pageable);
return ResponseEntity.ok(items);
log.info("상품 카드 리스트 조회 완료. 페이지: {}", pageable.getPageNumber());
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 카드 리스트가 조회되었습니다.", items),
HttpStatus.OK
);
}

@GetMapping("/list")
public ResponseEntity<List<ItemSimpleBackendDto>> getItemListForBackend(@RequestBody List<Long> itemId) {
List<ItemSimpleBackendDto> items = itemService.getItemListForBackend();
return ResponseEntity.ok(items);
}
// @GetMapping("/list")
// @Operation(summary = "백엔드용")
// public ResponseEntity<List<ItemSimpleBackendDto>> getItemListForBackend(@RequestBody List<Long> itemId) {
// List<ItemSimpleBackendDto> items = itemService.getItemListForBackend();
// return ResponseEntity.ok(items);
// }

@GetMapping("/managelist")
@Operation(summary = "상품 관리 리스트 조회", description = "페이지 정보에 따라 관리자용 상품 리스트를 조회합니다.")
public ResponseEntity<List<ItemManageListDto>> getItemManageList(Pageable pageable) {
public ResponseEntity<SuccessResponse<List<ItemManageListDto>>> getItemManageList(Pageable pageable) {
List<ItemManageListDto> items = itemService.getItemManageList(pageable);
return ResponseEntity.ok(items);
log.info("상품 관리 리스트 조회 완료. 페이지: {}", pageable.getPageNumber());
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 관리 리스트가 조회되었습니다.", items),
HttpStatus.OK
);
}

@GetMapping("/{itemId}")
@Operation(summary = "상품 상세 정보 조회", description = "상품 ID를 통해 상세한 상품 정보를 조회합니다.")
public ResponseEntity<ItemResponseDto> getItem(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId) {
public ResponseEntity<SuccessResponse<ItemResponseDto>> getItem(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId) {
ItemResponseDto item = itemService.getItem(itemId);
log.info("상품 상세 정보 조회 완료. 상품 ID: {}", item.getItemId());

return ResponseEntity.ok(item);
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(),"상품 상세 정보가 조회되었습니다.", item),
HttpStatus.OK
);
}

@GetMapping("/popular")
@Operation(summary = "인기 상품 조회", description = "지정된 상품 ID 리스트에 대한 인기 상품 정보를 페이지 정보에 따라 조회합니다.")
public ResponseEntity<List<PopularItemDto>> getPopularItems(@RequestBody List<Long> itemIdList, Pageable pageable) {
@Operation(summary = "인기 상품 리스트 조회", description = "지정된 상품 ID 리스트에 대한 인기 상품 정보를 페이지 정보에 따라 조회합니다.")
public ResponseEntity<SuccessResponse<List<PopularItemDto>>> getPopularItems(@RequestBody List<Long> itemIdList, Pageable pageable) {
List<PopularItemDto> popularItems = itemService.getPopularItems();
log.info("인기 상품 목록 조회 완료. 조회된 인기 상품 수: {}", popularItems.size());

return ResponseEntity.ok(popularItems);
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(),"인기 상품 리스트가 조회되었습니다.", popularItems),
HttpStatus.OK
);
}

@PutMapping("/{itemId}")
@Operation(summary = "상품 수정", description = "상품 ID에 해당하는 상품 정보를 수정합니다.")
public ResponseEntity<ItemResponseDto> updateItem(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @RequestBody ItemUpdateDto itemUpdateDto) {
public ResponseEntity<BaseResponse> updateItem(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @RequestBody ItemUpdateDto itemUpdateDto) {
ItemResponseDto item = itemService.updateItem(itemId, itemUpdateDto);
log.info("상품 정보 업데이트 완료. 상품 ID: {}", item.getItemId());

return ResponseEntity.ok(item);
return new ResponseEntity<>(
new BaseResponse(HttpStatus.CREATED.value(), "상품이 수정되었습니다."),
HttpStatus.CREATED
);
}

@DeleteMapping("/{itemId}")
@DeleteMapping("/{itemIds}")
@Operation(summary = "상품 삭제", description = "상품 ID에 해당하는 상품 정보를 삭제합니다.")
public ResponseEntity<Void> deleteItem(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId) {
itemService.deleteItem(itemId);
log.info("상품 정보 삭제 완료. 상품 ID: {}", itemId);

return ResponseEntity.noContent().build();
public ResponseEntity<BaseResponse> deleteItem(@PathVariable @Parameter(description = "상품ID", example = "1") List<Long> itemIds) {
itemService.deleteItem(itemIds);
log.info("상품 정보 삭제 완료. 상품 ID 리스트: {}", itemIds);
return new ResponseEntity<>(
new BaseResponse(HttpStatus.NO_CONTENT.value(), "상품이 삭제되었습니다."),
HttpStatus.NO_CONTENT
);
}

@GetMapping("/{itemId}/reviews")
@Operation(summary = "상품별 리뷰 리스트 조회", description = "페이지 정보에 따라 리뷰 리스트를 조회합니다.")
public ResponseEntity<List<ReviewResponseDto>> getReviewList(Pageable pageable) {
List<ReviewResponseDto> reviews = reviewService.getReviewList(pageable);
return ResponseEntity.ok(reviews);
@Operation(summary = "상품별 리뷰 리스트 조회", description = "상품별로 페이지 정보에 따라 리뷰 리스트를 조회합니다.")
public ResponseEntity<SuccessResponse<List<ReviewResponseDto>>> getReviewList(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, Pageable pageable) {
List<ReviewResponseDto> reviews = reviewService.getReviewList(itemId, pageable);
log.info("상품별 리뷰 리스트 조회 완료. 상품 ID: {}, 페이지 번호: {}", itemId, pageable.getPageNumber());
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품별 리뷰 리스트가 조회되었습니다.", reviews),
HttpStatus.OK
);
}

@GetMapping("/{itemId}/stock")
@Operation(summary = "재고 수량 조회", description = "재고 수량을 조회합니다.")
public ResponseEntity<Integer> getStockQuantity(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId) {
public ResponseEntity<SuccessResponse<Integer>> getStockQuantity(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId) {
int stockQuantity = itemService.getStockQuantity(itemId);
log.info("재고 수량 조회 완료. 상품 ID: {}", itemId);
return ResponseEntity.ok(stockQuantity);
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 재고 수량이 조회되었습니다.", stockQuantity),
HttpStatus.OK
);
}

@PutMapping("/{itemId}/increase/{quantity}")
@Operation(summary = "재고 수량 증가", description = "재고 수량을 증가시킵니다.")
public ResponseEntity<ItemResponseDto> increaseStock(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @PathVariable @Parameter(description = "재고 수량 입력", example = "100") int quantity) {
itemService.increaseStock(itemId, quantity);
public ResponseEntity<SuccessResponse<Integer>> increaseStock(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @PathVariable @Parameter(description = "재고 수량 입력", example = "100") int quantity) {
int increaseStock = itemService.increaseStock(itemId, quantity);
log.info("재고 수량 증가 완료. 상품 ID: {}", itemId);
return ResponseEntity.ok().build();
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 재고 수량이 증가되었습니다.", increaseStock),
HttpStatus.OK
);
}

@PutMapping("/{itemId}/decrease/{quantity}")
@Operation(summary = "재고 수량 감소", description = "재고 수량을 감소시킵니다.")
public ResponseEntity<ItemResponseDto> decreaseStock(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @PathVariable @Parameter(description = "재고 수량 입력", example = "100") int quantity) {
itemService.decreaseStock(itemId, quantity);
public ResponseEntity<SuccessResponse<Integer>> decreaseStock(@PathVariable @Parameter(description = "상품ID", example = "1") Long itemId, @PathVariable @Parameter(description = "재고 수량 입력", example = "100") int quantity) {
int decreaseStock = itemService.decreaseStock(itemId, quantity);
log.info("재고 수량 감소 완료. 상품 ID: {}", itemId);
return ResponseEntity.ok().build();
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 재고 수량이 조회되었습니다.", decreaseStock),
HttpStatus.OK
);
}

/* feign */
// event-server
@GetMapping("/findName")
@Operation(summary = "이벤트쪽 상품명 조회", description = "이벤트에 들어갈 상품명을 조회합니다.")
public ResponseEntity<String> getEventItemName(@RequestBody ItemResponseDto dto) {
String itemName = dto.getItemName();
return ResponseEntity.ok(itemName);
public ResponseEntity<SuccessResponse<String>> getEventItemName(@RequestBody Long itemId) {
String itemName = itemService.getItemName(itemId);
return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "상품 재고 수량이 조회되었습니다.", itemName),
HttpStatus.OK
);
}
}
}
33 changes: 20 additions & 13 deletions src/main/java/kea/dpang/item/controller/ReviewController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import kea.dpang.item.base.BaseResponse;
import io.swagger.v3.oas.annotations.tags.Tag;

import kea.dpang.item.base.*;
import kea.dpang.item.dto.*;
import kea.dpang.item.service.ReviewServiceImpl;

Expand All @@ -13,13 +15,13 @@
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.net.URI;
import java.util.List;

@RestController
@RequiredArgsConstructor
@Tag(name="Review API", description = "리뷰 관련 API 입니다.")
@RequestMapping("/api/reviews")
@Slf4j
public class ReviewController {
Expand Down Expand Up @@ -48,9 +50,14 @@ public ResponseEntity<BaseResponse> createReview(@RequestBody ReviewCreateDto re

@GetMapping("/{reviewerId}/reviewlist")
@Operation(summary = "사용자별 리뷰 리스트 조회", description = "사용자 정보에 따라 리뷰 리스트를 조회합니다.")
public ResponseEntity<List<ReviewPersonalListDto>> getReviewPersonalList(Pageable pageable) {
List<ReviewPersonalListDto> reviews = reviewService.getReviewPersonalList(pageable);
return ResponseEntity.ok(reviews);
public ResponseEntity<SuccessResponse<List<ReviewPersonalListDto>>> getReviewPersonalList(@PathVariable @Parameter(description = "리뷰 작성자 ID", example = "1") Long reviewerId, Pageable pageable) {
List<ReviewPersonalListDto> reviews = reviewService.getReviewPersonalList(reviewerId, pageable);
log.info("리뷰 리스트 조회 완료. 작성자 ID: {}", reviewerId);

return new ResponseEntity<>(
new SuccessResponse<>(HttpStatus.OK.value(), "리뷰 리스트가 조회되었습니다.", reviews),
HttpStatus.OK
);
}

// @PutMapping("/{reviewId}")
Expand All @@ -62,12 +69,12 @@ public ResponseEntity<List<ReviewPersonalListDto>> getReviewPersonalList(Pageabl
// return ResponseEntity.ok(review);
// }

@DeleteMapping("/{reviewId}")
@Operation(summary = "리뷰 삭제", description = "리뷰 정보를 시스템에서 제거합니다.")
public ResponseEntity<Void> deleteReview(@PathVariable @Parameter(description = "리뷰ID", example = "1") Long reviewId) {
reviewService.deleteReview(reviewId);
log.info("리뷰 삭제 완료. 리뷰 ID: {}", reviewId);

return ResponseEntity.noContent().build();
}
// @DeleteMapping("/{reviewId}")
// @Operation(summary = "리뷰 삭제", description = "리뷰 정보를 시스템에서 제거합니다.")
// public ResponseEntity<Void> deleteReview(@PathVariable @Parameter(description = "리뷰ID", example = "1") Long reviewId) {
// reviewService.deleteReview(reviewId);
// log.info("리뷰 삭제 완료. 리뷰 ID: {}", reviewId);
//
// return ResponseEntity.noContent().build();
// }
}
2 changes: 2 additions & 0 deletions src/main/java/kea/dpang/item/dto/ItemResponseDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
import kea.dpang.item.entity.Item;
import kea.dpang.item.entity.SubCategory;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@NoArgsConstructor
@Getter
public class ItemResponseDto {

private Long itemId;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/kea/dpang/item/dto/ReviewPersonalListDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,6 @@ public ReviewPersonalListDto(Review review) {
this.content = review.getContent();
this.rating = review.getRating();
}


}
15 changes: 15 additions & 0 deletions src/main/java/kea/dpang/item/feign/UserFeignClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package kea.dpang.item.feign;

import kea.dpang.item.base.SuccessResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(name = "user-server")
public interface UserFeignClient {

// 리뷰 작성자 이름을 받아오기 위한 API
@GetMapping("/api/users/reviewer/{reviewerId}")
ResponseEntity<SuccessResponse<String>> getReviewer (@PathVariable Long reviewerId);
}
Loading

0 comments on commit e77564d

Please sign in to comment.