Skip to content

Commit 76f76cd

Browse files
authored
Merge pull request #40 from YAPP-Github/feat/T3-125
[T3-125] 유저 닉네임 조회, 감정 구슬 조회 API
2 parents 3dbaff5 + 38eb008 commit 76f76cd

16 files changed

Lines changed: 221 additions & 26 deletions

src/main/java/bitnagil/bitnagil_backend/emotionMarble/controller/EmotionMarbleController.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88
import bitnagil.bitnagil_backend.global.annotation.CurrentUser;
99
import bitnagil.bitnagil_backend.global.response.CustomResponseDto;
1010
import bitnagil.bitnagil_backend.user.domain.User;
11+
import jakarta.validation.constraints.NotNull;
1112
import lombok.RequiredArgsConstructor;
13+
1214
import org.springframework.web.bind.annotation.*;
1315

16+
import java.time.LocalDate;
1417
import java.util.List;
1518

1619
@RestController
@@ -27,7 +30,19 @@ public CustomResponseDto<List<EmotionMarbleTypeResponse>> getEmotionMarbles() {
2730

2831
// 감정구슬 등록 API
2932
@PostMapping("")
30-
public CustomResponseDto<RegisterEmotionMarbleResponse> registryEmotionMarble(@CurrentUser User user, @RequestBody RegisterEmotionMarbleRequest request) {
33+
public CustomResponseDto<RegisterEmotionMarbleResponse> registryEmotionMarble(
34+
@CurrentUser User user,
35+
@RequestBody RegisterEmotionMarbleRequest request) {
36+
3137
return CustomResponseDto.from(emotionMarbleService.registryEmotionMarble(user, request));
3238
}
39+
40+
// 당일의 유저가 선택한 감정 구슬 조회 API
41+
@GetMapping("/me")
42+
public CustomResponseDto<EmotionMarbleTypeResponse> getEmotionMarbleForHome(
43+
@CurrentUser User user,
44+
@RequestParam @NotNull LocalDate searchDate) {
45+
46+
return CustomResponseDto.from(emotionMarbleService.getEmotionMarbleForHome(user, searchDate));
47+
}
3348
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/controller/spec/EmotionMarbleSpec.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,24 @@
33
import bitnagil.bitnagil_backend.emotionMarble.request.RegisterEmotionMarbleRequest;
44
import bitnagil.bitnagil_backend.emotionMarble.response.EmotionMarbleTypeResponse;
55
import bitnagil.bitnagil_backend.emotionMarble.response.RegisterEmotionMarbleResponse;
6+
import bitnagil.bitnagil_backend.global.annotation.CurrentUser;
67
import bitnagil.bitnagil_backend.global.errorcode.ErrorCode;
78
import bitnagil.bitnagil_backend.global.response.CustomResponseDto;
89
import bitnagil.bitnagil_backend.global.swagger.ApiErrorCodeExamples;
910
import bitnagil.bitnagil_backend.global.swagger.ApiTags;
1011
import bitnagil.bitnagil_backend.user.domain.User;
1112
import io.swagger.v3.oas.annotations.Operation;
13+
import io.swagger.v3.oas.annotations.Parameter;
14+
import io.swagger.v3.oas.annotations.Parameters;
1215
import io.swagger.v3.oas.annotations.tags.Tag;
16+
import jakarta.validation.constraints.NotNull;
1317

18+
import java.time.LocalDate;
1419
import java.util.List;
1520

21+
import org.springframework.format.annotation.DateTimeFormat;
22+
import org.springframework.web.bind.annotation.RequestParam;
23+
1624
@Tag(name = ApiTags.EMOTION_MARBLE)
1725
public interface EmotionMarbleSpec {
1826

@@ -21,5 +29,14 @@ public interface EmotionMarbleSpec {
2129

2230
@Operation(summary = "감정 구슬을 등록합니다. 감정 구슬에 따른 추천 루틴을 응답합니다.")
2331
@ApiErrorCodeExamples({ErrorCode.NOT_FOUND_RECOMMENDED_ROUTINE})
24-
public CustomResponseDto<RegisterEmotionMarbleResponse> registryEmotionMarble(User user, RegisterEmotionMarbleRequest request);
32+
public CustomResponseDto<RegisterEmotionMarbleResponse> registryEmotionMarble(
33+
User user, RegisterEmotionMarbleRequest request);
34+
35+
@Operation(summary = "검색 날짜 기준으로 대한 유저의 감정구슬 정보를 조회합니다.")
36+
@Parameters({
37+
@Parameter(name = "searchDate", description = "감정 구슬 조회 날짜", required = true, example = "2025-07-01")
38+
})
39+
CustomResponseDto<EmotionMarbleTypeResponse> getEmotionMarbleForHome(
40+
@CurrentUser User user,
41+
@RequestParam @NotNull LocalDate searchDate);
2542
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/response/EmotionMarbleTypeResponse.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ public class EmotionMarbleTypeResponse {
1717
@Schema(description = "감정 구슬 명칭", example = "평온함")
1818
private String emotionMarbleName;
1919

20-
@Schema(description = "감정 구슬 이미지 URL", example = "https://example.com/image/calm.png")
20+
@Schema(description = "감정 구슬 이미지 URL (홈/구슬 선택 화면 이미지 다름)", example = "https://example.com/image/calm.png")
2121
private String imageUrl;
2222
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/service/EmotionMarbleMapper.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package bitnagil.bitnagil_backend.emotionMarble.service;
22

3+
import bitnagil.bitnagil_backend.emotionMarble.domain.EmotionMarble;
34
import bitnagil.bitnagil_backend.emotionMarble.domain.enums.EmotionMarbleType;
45
import bitnagil.bitnagil_backend.emotionMarble.response.EmotionMarbleTypeResponse;
56
import org.springframework.stereotype.Component;
@@ -19,4 +20,12 @@ public EmotionMarbleTypeResponse toEmotionMarbleTypeResponse(EmotionMarbleType e
1920
.imageUrl(emotionMarbleType.getMarbleImageUrl())
2021
.build();
2122
}
23+
24+
public EmotionMarbleTypeResponse toEmotionMarbleTypeResponse(EmotionMarble emotionMarble) {
25+
return EmotionMarbleTypeResponse.builder()
26+
.emotionMarbleType(emotionMarble == null ? null : emotionMarble.getEmotionMarbleType())
27+
.emotionMarbleName(emotionMarble == null ? null : emotionMarble.getEmotionMarbleType().getDescription())
28+
.imageUrl(emotionMarble == null ? null :emotionMarble.getEmotionMarbleType().getHomeMarbleImageUrl())
29+
.build();
30+
}
2231
}

src/main/java/bitnagil/bitnagil_backend/emotionMarble/service/EmotionMarbleService.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,5 +70,14 @@ public RegisterEmotionMarbleResponse registryEmotionMarble(User user, RegisterEm
7070
.build();
7171
}
7272

73+
@Transactional(readOnly = true)
74+
public EmotionMarbleTypeResponse getEmotionMarbleForHome(User user, LocalDate searchDate) {
75+
EmotionMarble emotionMarble = emotionMarbleRepository.findByUserIdAndDateIs(
76+
user.getUserPk().getId(), searchDate);
77+
78+
return emotionMarbleMapper.toEmotionMarbleTypeResponse(emotionMarble);
79+
}
80+
81+
7382

7483
}

src/main/java/bitnagil/bitnagil_backend/onboarding/service/OnboardingService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import bitnagil.bitnagil_backend.recommendedRoutine.service.RecommendedRoutineManager;
2222
import bitnagil.bitnagil_backend.user.domain.User;
2323
import bitnagil.bitnagil_backend.user.repository.UserRepository;
24+
import bitnagil.bitnagil_backend.user.service.UserManager;
2425
import lombok.RequiredArgsConstructor;
2526

2627
import org.springframework.stereotype.Service;
@@ -46,6 +47,7 @@ public class OnboardingService {
4647

4748
private final RecommendedRoutineManager recommendedRoutineManager;
4849
private final ChangedRoutineFactory changedRoutineFactory;
50+
private final UserManager userManager;
4951

5052
/**
5153
* 유저와 매칭되는 온보딩 결과를 설정하고, 리턴하는 메서드
@@ -62,9 +64,8 @@ public CustomResponseDto<OnboardingResponse> startOnboarding(OnboardingRequest r
6264
);
6365

6466
// 회원은 온보딩과의 연관관계를 설정한다.
65-
user = userRepository.findByUserPk(user.getUserPk()).orElseThrow(
66-
() -> new CustomException(ErrorCode.NOT_FOUND_USER));
67-
user.updateOnboarding(onboarding);
67+
User persistedUser = userManager.getPersistedUser(user);
68+
persistedUser.updateOnboarding(onboarding);
6869

6970
// 온보딩의 CASE를 통해 추천루틴을 조회한다.
7071
List<RecommendedRoutineDto> recommendedRoutineDtoList =

src/main/java/bitnagil/bitnagil_backend/recommendedRoutine/service/RecommendedRoutineManager.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.util.stream.Collectors;
55

66
import org.springframework.stereotype.Component;
7+
import org.springframework.stereotype.Service;
78

89
import bitnagil.bitnagil_backend.global.errorcode.ErrorCode;
910
import bitnagil.bitnagil_backend.global.exception.CustomException;
@@ -15,7 +16,10 @@
1516
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedSubRoutineSearchResult;
1617
import lombok.RequiredArgsConstructor;
1718

18-
@Component
19+
/**
20+
* 외부에서 사용되는 추천 루틴에 대한 공통 로직을 관리하는 클래스입니다.
21+
*/
22+
@Service
1923
@RequiredArgsConstructor
2024
public class RecommendedRoutineManager {
2125

src/main/java/bitnagil/bitnagil_backend/recommendedRoutine/service/RecommendedRoutineMapper.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package bitnagil.bitnagil_backend.recommendedRoutine.service;
22

33
import java.util.List;
4+
import java.util.Map;
45

56
import org.springframework.stereotype.Component;
67

8+
import bitnagil.bitnagil_backend.emotionMarble.domain.EmotionMarble;
79
import bitnagil.bitnagil_backend.recommendedRoutine.domain.RecommendedRoutine;
810
import bitnagil.bitnagil_backend.recommendedRoutine.domain.RecommendedSubRoutine;
11+
import bitnagil.bitnagil_backend.recommendedRoutine.domain.enums.RecommendedRoutineType;
912
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineDto;
13+
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineSearchResponse;
1014
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineSearchResult;
1115
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedSubRoutineSearchResult;
1216

@@ -51,4 +55,14 @@ public RecommendedSubRoutineSearchResult toRecommendedSubRoutineSearchResult(
5155
.recommendedSubRoutineName(recommendedSubRoutine.getSubRoutineName())
5256
.build();
5357
}
58+
59+
// 추천 카테고리 별 루틴, 서브루틴을 반환하는 DTO로 변환
60+
public RecommendedRoutineSearchResponse toRecommendedRoutineSearchResponse(
61+
Map<RecommendedRoutineType, List<RecommendedRoutineSearchResult>> response, EmotionMarble emotionMarble) {
62+
63+
return RecommendedRoutineSearchResponse.builder()
64+
.recommendedRoutines(response)
65+
.emotionMarbleType(emotionMarble == null ? null : emotionMarble.getEmotionMarbleType()) // 감정 구슬 타입 설정
66+
.build();
67+
}
5468
}

src/main/java/bitnagil/bitnagil_backend/recommendedRoutine/service/RecommendedRoutineService.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedRoutineSearchResult;
1616
import bitnagil.bitnagil_backend.recommendedRoutine.response.RecommendedSubRoutineSearchResult;
1717
import bitnagil.bitnagil_backend.user.domain.User;
18-
import bitnagil.bitnagil_backend.user.repository.UserRepository;
18+
import bitnagil.bitnagil_backend.user.service.UserManager;
1919
import lombok.RequiredArgsConstructor;
2020
import lombok.extern.slf4j.Slf4j;
2121

@@ -38,9 +38,9 @@ public class RecommendedRoutineService {
3838
private final RecommendedRoutineRepository recommendedRoutineRepository;
3939
private final RecommendedSubRoutineRepository recommendedSubRoutineRepository;
4040
private final EmotionMarbleRepository emotionMarbleRepository;
41-
private final UserRepository userRepository;
4241

4342
private final RecommendedRoutineMapper recommendedRoutineMapper;
43+
private final UserManager userManager;
4444

4545
/**
4646
* 추천 카테고리별 루틴, 서브루틴을 조회
@@ -56,19 +56,15 @@ public RecommendedRoutineSearchResponse searchRecommendedRoutines(User user) {
5656
response.put(RecommendedRoutineType.PERSONALIZED, new ArrayList<>()); // 맞춤 루틴은 미리 초기화 한다.(감정구슬, 온보딩 결과를 넣기 위해)
5757

5858
// 영속성 객체에 user를 저장하기 위해 user를 조회
59-
user = userRepository.findByUserPk(user.getUserPk())
60-
.orElseThrow(() -> new CustomException(ErrorCode.NOT_FOUND_USER));
59+
User persistedUser = userManager.getPersistedUser(user);
6160

6261
// 맞춤 추천(감정구슬 + 온보딩)을 조회하고 response에 추가
63-
EmotionMarble emotionMarble = addPersonalizedRecommendedRoutine(user, nowDate, response);
62+
EmotionMarble emotionMarble = addPersonalizedRecommendedRoutine(persistedUser, nowDate, response);
6463

6564
// 맞춤추천 이외의 카테고리에 대한 추천 루틴을 response 추가
6665
addCategoryRecommendedRoutines(response);
6766

68-
return RecommendedRoutineSearchResponse.builder()
69-
.recommendedRoutines(response)
70-
.emotionMarbleType(emotionMarble == null ? null : emotionMarble.getEmotionMarbleType()) // 감정 구슬 타입 설정
71-
.build();
67+
return recommendedRoutineMapper.toRecommendedRoutineSearchResponse(response, emotionMarble);
7268
}
7369

7470
/**
@@ -108,7 +104,7 @@ private void addCategoryRecommendedRoutines(Map<RecommendedRoutineType, List<Rec
108104
}
109105
}
110106

111-
private EmotionMarble addPersonalizedRecommendedRoutine(User user, LocalDate nowDate,
107+
private EmotionMarble addPersonalizedRecommendedRoutine(User user, LocalDate nowDate,
112108
Map<RecommendedRoutineType, List<RecommendedRoutineSearchResult>> response) {
113109
// 감정구슬(당일에 감정구슬을 선택한 경우만 조회)
114110
EmotionMarble emotionMarble = emotionMarbleRepository.findByUserIdAndDateIs(user.getUserPk().getId(), nowDate);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package bitnagil.bitnagil_backend.user.controller;
2+
3+
import org.springframework.web.bind.annotation.GetMapping;
4+
import org.springframework.web.bind.annotation.RequestMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
import bitnagil.bitnagil_backend.global.annotation.CurrentUser;
8+
import bitnagil.bitnagil_backend.global.response.CustomResponseDto;
9+
import bitnagil.bitnagil_backend.user.controller.spec.UserSpec;
10+
import bitnagil.bitnagil_backend.user.domain.User;
11+
import bitnagil.bitnagil_backend.user.response.UserInfoResponse;
12+
import bitnagil.bitnagil_backend.user.service.UserService;
13+
import lombok.RequiredArgsConstructor;
14+
15+
@RestController
16+
@RequiredArgsConstructor
17+
@RequestMapping(value = "/api/v1/users")
18+
public class UserController implements UserSpec {
19+
20+
private final UserService userService;
21+
22+
@GetMapping("/nickname")
23+
public CustomResponseDto<UserInfoResponse> getUserInfo(@CurrentUser User user) {
24+
UserInfoResponse userInfoResponse = userService.getUserInfo(user);
25+
26+
return CustomResponseDto.from(userInfoResponse);
27+
}
28+
}

0 commit comments

Comments
 (0)