-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat] 인벤토리 API #46
[Feat] 인벤토리 API #46
Changes from 6 commits
82880a0
d237241
c588e64
c038b8f
720a2ee
7329c6c
e4b2af0
ec3fee0
d5fa66c
f170ea8
bf48b29
f7472c8
55b1214
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package ku.user.domain.character.exception; | ||
|
||
import ku.user.global.exception.CustomException; | ||
import ku.user.global.exception.ErrorCode; | ||
|
||
public class CurrentMoneyLeakException extends CustomException { | ||
public CurrentMoneyLeakException() { | ||
super("현재 재화가 부족합니다.", ErrorCode.INTERNAL_SERVER_ERROR); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package ku.user.domain.inventory.controller; | ||
|
||
import ku.user.domain.inventory.domain.Inventory; | ||
import ku.user.domain.inventory.domain.ItemType; | ||
import ku.user.domain.inventory.dto.request.PostItemRequest; | ||
import ku.user.domain.inventory.dto.response.GetInventoryResponse; | ||
import ku.user.domain.inventory.dto.response.PostItemResponse; | ||
import ku.user.domain.inventory.service.InventoryService; | ||
import ku.user.global.response.ApiResponse; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
public class InventoryController { | ||
|
||
private final InventoryService inventoryService; | ||
|
||
@GetMapping("/inventorys") | ||
public ApiResponse<GetInventoryResponse> GetInventory(@RequestParam String email) { | ||
Inventory inventory = inventoryService.getInventoryByEmail(email); | ||
GetInventoryResponse getInventoryResponse = GetInventoryResponse.toDto(inventory); | ||
return new ApiResponse<>(true,getInventoryResponse,null); | ||
} | ||
|
||
@PostMapping("/items") | ||
public ApiResponse<PostItemResponse> PostItem(@RequestParam String email, @RequestBody PostItemRequest postItemRequest) { | ||
Inventory inventory = inventoryService.buyItem(email, postItemRequest.getItemType()); | ||
PostItemResponse postItemResponse = PostItemResponse.toDto(inventory); | ||
return new ApiResponse<>(true,postItemResponse,null); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package ku.user.domain.inventory.dao; | ||
|
||
import ku.user.domain.inventory.domain.Inventory; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.stereotype.Repository; | ||
|
||
import java.util.Optional; | ||
|
||
@Repository | ||
public interface InventoryRepository extends JpaRepository<Inventory, Long> { | ||
|
||
Optional<Inventory> findByUserId(Long userId); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package ku.user.domain.inventory.dao; | ||
|
||
import ku.user.domain.inventory.domain.Item; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
public interface ItemRepository extends JpaRepository<Item, Long> { | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package ku.user.domain.inventory.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Table(name = "inventorys") | ||
@Builder | ||
@Getter | ||
public class Inventory { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
private Long userId; | ||
|
||
@OneToMany(mappedBy = "inventory") | ||
private List<Item> itemList = new ArrayList<>(); | ||
|
||
public static Inventory from(Long userId) { | ||
return Inventory.builder() | ||
.userId(userId) | ||
.build(); | ||
} | ||
|
||
public void addItem(Item item) { | ||
itemList.add(item); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package ku.user.domain.inventory.domain; | ||
|
||
import jakarta.persistence.*; | ||
import lombok.*; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
@Table(name = "items") | ||
@Builder | ||
@Getter | ||
public class Item { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@ManyToOne | ||
@JoinColumn(name = "item_id") | ||
private Inventory inventory; | ||
|
||
private ItemType itemType; | ||
|
||
public static Item from(Inventory inventory, ItemType itemType){ | ||
return Item.builder() | ||
.itemType(itemType) | ||
.inventory(inventory) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package ku.user.domain.inventory.domain; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public enum ItemType { | ||
|
||
//오로라 | ||
AURORA(1L, 100), | ||
//킥보드 | ||
KICK_BOARD(2L, 100), | ||
//칭호 | ||
TITLE(3L, 100); | ||
private Long itemNumber; | ||
private int price; | ||
|
||
ItemType(Long itemNumber, int price) { | ||
this.itemNumber = itemNumber; | ||
this.price = price; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package ku.user.domain.inventory.dto.request; | ||
|
||
import ku.user.domain.inventory.domain.ItemType; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
public class PostItemRequest { | ||
|
||
private ItemType itemType; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package ku.user.domain.inventory.dto.response; | ||
|
||
import ku.user.domain.inventory.domain.Inventory; | ||
import ku.user.domain.inventory.domain.Item; | ||
import lombok.Builder; | ||
|
||
import java.util.List; | ||
|
||
@Builder | ||
public record GetInventoryResponse(Long id, | ||
Long userId, | ||
List<GetItemResponse> itemList) { | ||
|
||
public static GetInventoryResponse toDto(Inventory inventory) { | ||
|
||
List<GetItemResponse> getItemResponseList = inventory.getItemList().stream().map(GetItemResponse::toDto).toList(); | ||
|
||
return GetInventoryResponse.builder() | ||
.id(inventory.getId()) | ||
.userId(inventory.getUserId()) | ||
.itemList(getItemResponseList) | ||
.build(); | ||
|
||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package ku.user.domain.inventory.dto.response; | ||
|
||
import ku.user.domain.inventory.domain.Item; | ||
import ku.user.domain.inventory.domain.ItemType; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record GetItemResponse(Long id, | ||
ItemType itemType, | ||
Long itemNumber) { | ||
public static GetItemResponse toDto(Item item) { | ||
return GetItemResponse.builder() | ||
.id(item.getId()) | ||
.itemType(item.getItemType()) | ||
.itemNumber(item.getItemType().getItemNumber()) | ||
.build(); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package ku.user.domain.inventory.dto.response; | ||
|
||
import ku.user.domain.inventory.domain.Inventory; | ||
import ku.user.domain.inventory.domain.Item; | ||
import ku.user.domain.inventory.domain.ItemType; | ||
import lombok.Builder; | ||
|
||
import java.util.List; | ||
|
||
/** | ||
* 아이템 추가 API Response | ||
* @param id | ||
* @param userId | ||
* @param itemList | ||
* 아이템을 추가하지만 인밴토리를 반환한다. | ||
*/ | ||
@Builder | ||
public record PostItemResponse(Long id, | ||
Long userId, | ||
List<GetItemResponse> itemList) { | ||
|
||
public static PostItemResponse toDto(Inventory inventory) { | ||
|
||
List<GetItemResponse> getItemResponseList = inventory.getItemList().stream().map(GetItemResponse::toDto).toList(); | ||
|
||
return PostItemResponse.builder() | ||
.id(inventory.getId()) | ||
.userId(inventory.getUserId()) | ||
.itemList(getItemResponseList) | ||
.build(); | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package ku.user.domain.inventory.service; | ||
|
||
import ku.user.domain.character.domain.Character; | ||
import ku.user.domain.character.service.CharacterService; | ||
import ku.user.domain.inventory.dao.InventoryRepository; | ||
import ku.user.domain.inventory.dao.ItemRepository; | ||
import ku.user.domain.inventory.domain.Inventory; | ||
import ku.user.domain.inventory.domain.Item; | ||
import ku.user.domain.inventory.domain.ItemType; | ||
import ku.user.domain.user.service.UserService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
import java.util.Optional; | ||
|
||
@Service | ||
@RequiredArgsConstructor | ||
public class InventoryService { | ||
|
||
private final InventoryRepository inventoryRepository; | ||
private final ItemRepository itemRepository; | ||
private final UserService userService; | ||
private final CharacterService characterService; | ||
|
||
|
||
@Transactional | ||
public Inventory findByUserId(Long userId){ | ||
Optional<Inventory> inventoryOptional = inventoryRepository.findByUserId(userId); | ||
if(inventoryOptional.isEmpty()) | ||
throw new RuntimeException("해당하는 인벤토리가 없습니다. 회원가입된 아이디가 아닙니다."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 예외 내용에 두 가지가 들어가는거 같은데 이유가 있을까요? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return inventoryOptional.get(); | ||
} | ||
|
||
@Transactional | ||
public Inventory save(Inventory inventory) { | ||
return inventoryRepository.save(inventory); | ||
} | ||
|
||
@Transactional | ||
public Item saveItem(Item item) { | ||
return itemRepository.save(item); | ||
} | ||
|
||
/** | ||
* 유저가 생성될때, 인벤토리 엔티티를 추가한다. | ||
* | ||
* @param userId 유저id | ||
* @return 생성된 인벤토리 | ||
*/ | ||
@Transactional | ||
public Inventory createInventory(Long userId) { | ||
Inventory inventory = Inventory.from(userId); | ||
return save(inventory); | ||
} | ||
|
||
/** | ||
* 유저 이메일에 대한 인벤토리를 찾는다. | ||
* | ||
* @param email 유저 이메일 | ||
* @return 인벤토리 | ||
*/ | ||
@Transactional(readOnly = true) | ||
public Inventory getInventoryByEmail(String email) { | ||
|
||
Long userId = userService.getByEmail(email).getId(); | ||
Optional<Inventory> inventoryOptional = inventoryRepository.findByUserId(userId); | ||
|
||
return inventoryOptional.get(); | ||
} | ||
|
||
/** | ||
* 이메일해당하는 유저가 아이템을 산다 | ||
* @param email | ||
* @param itemType | ||
* @return | ||
*/ | ||
@Transactional | ||
public Inventory buyItem(String email, ItemType itemType) { | ||
Character character = characterService.payPriceByEmail(email, itemType.getPrice()); | ||
Long userId = character.getUserId(); | ||
Inventory findInventory = findByUserId(userId); | ||
Inventory updatInventory = addItem(findInventory, itemType); | ||
return updatInventory; | ||
} | ||
|
||
/** | ||
* 인벤토리에 아이템을 저장하고 추가한다. | ||
* @param findInventory 인벤토리 | ||
* @param itemType 추가할 아이템 | ||
* @return 인벤토리 | ||
* 트랙잭션 전파를 사용한다. | ||
*/ | ||
private Inventory addItem(Inventory findInventory, ItemType itemType) { | ||
Item item = Item.from(findInventory, itemType); | ||
Item saveItem = saveItem(item); | ||
findInventory.addItem(saveItem); | ||
return findInventory; | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR 본문에도 궁금했던 내용인데 유저와 인벤토리가 연결되는 이유를 모르겠습니다. 인벤토리는 캐릭터와 연결되는게 맞는 그림이 아닌가 생각하는데 의도하신 이유가 궁금합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
잘못생각했습니다. 캐릭터와 관계를 가져야 하는 것이 맞다고 생각합니다