diff --git a/api-service/src/main/java/com/codingland/apiservice/character/presentation/CharacterController.java b/api-service/src/main/java/com/codingland/apiservice/character/presentation/CharacterController.java index c56b18d..f84292e 100644 --- a/api-service/src/main/java/com/codingland/apiservice/character/presentation/CharacterController.java +++ b/api-service/src/main/java/com/codingland/apiservice/character/presentation/CharacterController.java @@ -2,6 +2,7 @@ import com.codingland.common.common.ApplicationResponse; import com.codingland.domain.character.dto.RequestCharacterDto; +import com.codingland.domain.character.dto.ResponseCharacterDto; import com.codingland.domain.character.dto.ResponseCreateCharacterDto; import com.codingland.domain.character.service.CharacterService; import com.codingland.domain.user.entity.User; @@ -54,4 +55,13 @@ public ApplicationResponse decreasedCharacter(@RequestParam Long character characterService.decreasedPoint(character_id, activityPoint); return ApplicationResponse.ok(null); } + + @GetMapping("/pickup/random") + @Operation(summary = "캐릭터 랜덤 뽑기 후 홈화면 선인장 교체", description = """ + (사용자) 캐릭터를 랜덤 뽑기 한 후 홈화면에 있는 선인장을 새롭게 뽑은 선인장으로 교체합니다. + """) + public ApplicationResponse getRandomCharacter(@UserResolver User user) { + ResponseCharacterDto result = characterService.pickRandomCharacter(user.getUserId()); + return ApplicationResponse.ok(result); + } } diff --git a/api-service/src/main/java/com/codingland/apiservice/home/presentation/HomeController.java b/api-service/src/main/java/com/codingland/apiservice/home/presentation/HomeController.java index 670fbc3..c9a5ff7 100644 --- a/api-service/src/main/java/com/codingland/apiservice/home/presentation/HomeController.java +++ b/api-service/src/main/java/com/codingland/apiservice/home/presentation/HomeController.java @@ -69,6 +69,7 @@ public ResponseEntity deleteHome(@PathVariable Long home_id) { homeService.deleteHome(home_id); return ResponseEntity.status(HttpStatus.OK).body(null); } + } diff --git a/common/src/main/java/com/codingland/common/exception/character/CharacterErrorCode.java b/common/src/main/java/com/codingland/common/exception/character/CharacterErrorCode.java index e51c495..6da5f48 100644 --- a/common/src/main/java/com/codingland/common/exception/character/CharacterErrorCode.java +++ b/common/src/main/java/com/codingland/common/exception/character/CharacterErrorCode.java @@ -10,6 +10,7 @@ @AllArgsConstructor public enum CharacterErrorCode implements BaseErrorCode { NOT_FOUND_CHARACTER_ERROR(HttpStatus.BAD_REQUEST, "2000", "캐릭터 정보가 정보가 존재하지 않습니다."), + IT_IS_NOT_YOUR_CHARACTER(HttpStatus.BAD_REQUEST, "2000", "사용자의 캐릭터가 아닙니다.") ; private final HttpStatus httpStatus; private final String code; diff --git a/domain/src/main/java/com/codingland/domain/character/common/CactusType.java b/domain/src/main/java/com/codingland/domain/character/common/CactusType.java new file mode 100644 index 0000000..61e3feb --- /dev/null +++ b/domain/src/main/java/com/codingland/domain/character/common/CactusType.java @@ -0,0 +1,5 @@ +package com.codingland.domain.character.common; + +public enum CactusType { + KING_CACTUS, HERO_CACTUS +} diff --git a/domain/src/main/java/com/codingland/domain/character/common/CharacterTypeEnum.java b/domain/src/main/java/com/codingland/domain/character/common/ProgressEnum.java similarity index 73% rename from domain/src/main/java/com/codingland/domain/character/common/CharacterTypeEnum.java rename to domain/src/main/java/com/codingland/domain/character/common/ProgressEnum.java index ad36330..462b49c 100644 --- a/domain/src/main/java/com/codingland/domain/character/common/CharacterTypeEnum.java +++ b/domain/src/main/java/com/codingland/domain/character/common/ProgressEnum.java @@ -1,5 +1,5 @@ package com.codingland.domain.character.common; -public enum CharacterTypeEnum { +public enum ProgressEnum { LEVEL_LOW, LEVEL_MEDIUM, LEVEL_HIGH } diff --git a/domain/src/main/java/com/codingland/domain/character/dto/ResponseCharacterDto.java b/domain/src/main/java/com/codingland/domain/character/dto/ResponseCharacterDto.java index 14c14d5..3caf97b 100644 --- a/domain/src/main/java/com/codingland/domain/character/dto/ResponseCharacterDto.java +++ b/domain/src/main/java/com/codingland/domain/character/dto/ResponseCharacterDto.java @@ -1,6 +1,7 @@ package com.codingland.domain.character.dto; -import com.codingland.domain.character.common.CharacterTypeEnum; +import com.codingland.domain.character.common.CactusType; +import com.codingland.domain.character.common.ProgressEnum; import lombok.Builder; @Builder @@ -8,7 +9,8 @@ public record ResponseCharacterDto( Long id, String name, int level, - CharacterTypeEnum type, + ProgressEnum type, + CactusType cactusType, int activityPoints ) { } diff --git a/domain/src/main/java/com/codingland/domain/character/entity/Character.java b/domain/src/main/java/com/codingland/domain/character/entity/Character.java index 8e9b745..bcf0c08 100644 --- a/domain/src/main/java/com/codingland/domain/character/entity/Character.java +++ b/domain/src/main/java/com/codingland/domain/character/entity/Character.java @@ -1,8 +1,11 @@ package com.codingland.domain.character.entity; -import com.codingland.domain.character.common.CharacterTypeEnum; +import com.codingland.domain.character.common.CactusType; +import com.codingland.domain.character.common.ProgressEnum; +import com.codingland.domain.user.entity.User; import jakarta.persistence.*; import lombok.AccessLevel; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -18,11 +21,19 @@ public class Character { private Long id; private String name; private int level = 0; - private CharacterTypeEnum type = CharacterTypeEnum.LEVEL_LOW; + private ProgressEnum type = ProgressEnum.LEVEL_LOW; + private CactusType cactus = CactusType.KING_CACTUS; private int activityPoints = 0; - public Character(String name) { + @ManyToOne + @JoinColumn(name = "user_user_id") + private User user; + + @Builder + public Character(String name, CactusType cactus, User user) { this.name = name; + this.cactus = cactus; + this.user = user; } public void editName(String name) { this.name = name; @@ -37,9 +48,9 @@ public void increaseActivityPoints(int point) { } if (this.level > 10) { - this.type = CharacterTypeEnum.LEVEL_HIGH; + this.type = ProgressEnum.LEVEL_HIGH; } else if (this.level > 5) { - this.type = CharacterTypeEnum.LEVEL_MEDIUM; + this.type = ProgressEnum.LEVEL_MEDIUM; } } @@ -55,11 +66,11 @@ public void decreaseActivityPoints(int point) { this.level = newLevel; if (this.level > 10) { - this.type = CharacterTypeEnum.LEVEL_HIGH; + this.type = ProgressEnum.LEVEL_HIGH; } else if (this.level > 5) { - this.type = CharacterTypeEnum.LEVEL_MEDIUM; + this.type = ProgressEnum.LEVEL_MEDIUM; } else { - this.type = CharacterTypeEnum.LEVEL_LOW; + this.type = ProgressEnum.LEVEL_LOW; } } } diff --git a/domain/src/main/java/com/codingland/domain/character/repository/CharacterRepository.java b/domain/src/main/java/com/codingland/domain/character/repository/CharacterRepository.java index 8e61b7c..27b9cde 100644 --- a/domain/src/main/java/com/codingland/domain/character/repository/CharacterRepository.java +++ b/domain/src/main/java/com/codingland/domain/character/repository/CharacterRepository.java @@ -1,7 +1,11 @@ package com.codingland.domain.character.repository; import com.codingland.domain.character.entity.Character; +import com.codingland.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; +import java.util.List; + public interface CharacterRepository extends JpaRepository { + List findCharacterByUser(User user); } diff --git a/domain/src/main/java/com/codingland/domain/character/service/CharacterService.java b/domain/src/main/java/com/codingland/domain/character/service/CharacterService.java index e0d4b19..f3a85a4 100644 --- a/domain/src/main/java/com/codingland/domain/character/service/CharacterService.java +++ b/domain/src/main/java/com/codingland/domain/character/service/CharacterService.java @@ -2,9 +2,13 @@ import com.codingland.common.exception.character.CharacterErrorCode; import com.codingland.common.exception.character.CharacterException; +import com.codingland.common.exception.home.HomeErrorCode; +import com.codingland.common.exception.home.HomeException; import com.codingland.common.exception.user.UserErrorCode; import com.codingland.common.exception.user.UserException; +import com.codingland.domain.character.common.CactusType; import com.codingland.domain.character.dto.RequestCharacterDto; +import com.codingland.domain.character.dto.ResponseCharacterDto; import com.codingland.domain.character.dto.ResponseCreateCharacterDto; import com.codingland.domain.character.entity.Character; import com.codingland.domain.character.repository.CharacterRepository; @@ -15,6 +19,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.Random; + @Service @RequiredArgsConstructor public class CharacterService { @@ -32,10 +38,13 @@ public class CharacterService { * @throws UserException 유저를 찾지 못했을 때 반환되는 예외 */ public ResponseCreateCharacterDto createCharacter(Long user_id, RequestCharacterDto requestCharacterDto) { - Character newCharacter = new Character(requestCharacterDto.name()); - Character savedCharacter = characterRepository.save(newCharacter); User foundUser = userRepository.findById(user_id) .orElseThrow(() -> new UserException(UserErrorCode.No_USER_INFO)); + Character newCharacter = Character.builder() + .name(requestCharacterDto.name()) + .user(foundUser) + .build(); + Character savedCharacter = characterRepository.save(newCharacter); Home newHome = new Home(foundUser, savedCharacter); Home savedHome = homeRepository.save(newHome); return new ResponseCreateCharacterDto(savedCharacter.getId(), savedHome.getId()); @@ -83,5 +92,45 @@ public void decreasedPoint(Long character_id, int decreased_point) { characterRepository.save(foundCharacter); } + /** + * 유저가 가지고 있는 캐릭터를 전체 조회하는 메서드 + * @author 김원정 + */ + + /** + * 캐릭터 랜덤 뽑기한 다음에 홈 화면의 선인장을 바꾸는 메서드입니다. + * @author 김원정 + * @param user_id 랜덤 뽑기를 하는 유저 id + * @throws UserException 유저가 존재하지 않을 경우 발생하는 예외 + * @throws HomeException 등록된 홈이 존재하지 않을 경우 발생하는 예외 + */ + public ResponseCharacterDto pickRandomCharacter(Long user_id) { + User foundUser = userRepository.findById(user_id) + .orElseThrow(() -> new UserException(UserErrorCode.No_USER_INFO)); + Character foundCharacter = characterRepository.findCharacterByUser(foundUser) + .getFirst(); + Random random = new Random(); + int index = random.nextInt(CactusType.values().length - 1) + 1; + CactusType randomCactusType = CactusType.values()[index]; + Character newCharacter = Character.builder() + .name(foundCharacter.getName()) + .cactus(randomCactusType) + .user(foundUser) + .build(); + Character savedCharacter = characterRepository.save(newCharacter); + Home foundHome = homeRepository.findHomeByUserUserId(user_id) + .orElseThrow(() -> new HomeException(HomeErrorCode.NO_HOME_INFO)); + foundHome.changeCharacter(savedCharacter); + homeRepository.save(foundHome); + return ResponseCharacterDto.builder() + .id(savedCharacter.getId()) + .name(savedCharacter.getName()) + .level(savedCharacter.getLevel()) + .type(savedCharacter.getType()) + .cactusType(savedCharacter.getCactus()) + .activityPoints(savedCharacter.getActivityPoints()) + .build(); + } + } diff --git a/domain/src/main/java/com/codingland/domain/home/entity/Home.java b/domain/src/main/java/com/codingland/domain/home/entity/Home.java index 5b3f841..a18cc13 100644 --- a/domain/src/main/java/com/codingland/domain/home/entity/Home.java +++ b/domain/src/main/java/com/codingland/domain/home/entity/Home.java @@ -32,4 +32,7 @@ public Home(User user, Character character) { public void editHome(RequestEditHomeDto requestEditHomeDto) { this.id = requestEditHomeDto.id(); } + public void changeCharacter(Character character) { + this.character = character; + } } diff --git a/domain/src/main/java/com/codingland/domain/home/service/HomeService.java b/domain/src/main/java/com/codingland/domain/home/service/HomeService.java index f5ad207..19c0a45 100644 --- a/domain/src/main/java/com/codingland/domain/home/service/HomeService.java +++ b/domain/src/main/java/com/codingland/domain/home/service/HomeService.java @@ -1,13 +1,21 @@ package com.codingland.domain.home.service; +import com.codingland.common.exception.character.CharacterErrorCode; +import com.codingland.common.exception.character.CharacterException; import com.codingland.common.exception.home.HomeErrorCode; import com.codingland.common.exception.home.HomeException; +import com.codingland.common.exception.user.UserErrorCode; +import com.codingland.common.exception.user.UserException; import com.codingland.domain.character.dto.ResponseCharacterDto; +import com.codingland.domain.character.entity.Character; +import com.codingland.domain.character.repository.CharacterRepository; import com.codingland.domain.home.dto.RequestEditHomeDto; import com.codingland.domain.home.dto.ResponseHomeDto; import com.codingland.domain.home.dto.ResponseHomeListDto; import com.codingland.domain.home.entity.Home; import com.codingland.domain.home.repository.HomeRepository; +import com.codingland.domain.user.entity.User; +import com.codingland.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,6 +27,8 @@ public class HomeService { private final HomeRepository homeRepository; + private final CharacterRepository characterRepository; + private final UserRepository userRepository; /** * 홈을 생성합니다. @@ -48,6 +58,7 @@ public ResponseHomeDto getHome(Long user_id) { .level(foundHome.getCharacter().getLevel()) .type(foundHome.getCharacter().getType()) .activityPoints(foundHome.getCharacter().getActivityPoints()) + .cactusType(foundHome.getCharacter().getCactus()) .build(), foundHome.getUser().getPicture() ); @@ -101,4 +112,25 @@ public void deleteHome(Long homeId) { .orElseThrow(() -> new HomeException(HomeErrorCode.NO_HOME_INFO)); homeRepository.delete(home); } + + /** + * 홈에 설정된 캐릭터를 바꿉니다. + * @author 김원정 + * @param home_id 캐릭터가 바뀔 홈 id + * @param character_id 바뀔 캐릭터 id + * @param user_id 유저의 캐릭터인지 확인하기 위해 필요한 Id + */ + public void changeCharacter(Long home_id, Long character_id, Long user_id) { + Home foundHome = homeRepository.findById(home_id) + .orElseThrow(() -> new HomeException(HomeErrorCode.NO_HOME_INFO)); + Character foundCharacter = characterRepository.findById(character_id) + .orElseThrow(() -> new CharacterException(CharacterErrorCode.NOT_FOUND_CHARACTER_ERROR)); + User foundUser = userRepository.findById(user_id) + .orElseThrow(() -> new UserException(UserErrorCode.No_USER_INFO)); + if (!foundCharacter.getUser().getUserId().equals(foundUser.getUserId())) { + throw new CharacterException(CharacterErrorCode.IT_IS_NOT_YOUR_CHARACTER); + } + foundHome.changeCharacter(foundCharacter); + homeRepository.save(foundHome); + } }