📂 apiPayload
📂 config
📂 controller
L MainController
📂 domain
L 📂 common
L 📂 enums
L User
L Food
📂 dto
L 📂 request
L 📂 response
L MainStatisticsResponseDto
L MainStatisticsResponseListDto
📂 jwt
📂 repository
L UserRepository
L FoodRepository
📂 service
L MainService
L MainServiceImpl
날짜별로 칼로리, 탄수화물량, 단백질량, 지방량 정보를 확인할 수 있도록 전달하자
① MainStatisticsResponseListDto : 날짜별로 데이터를 묶어준다
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MainStatisticsResponseListDto {
private List<MainStatisticsResponseDto> data;
public static MainStatisticsResponseListDto mainStatisticsResponseList(List<MainStatisticsResponseDto> dtoList, List<LocalDate> allDates) {
// 날짜별로 데이터를 맵핑
Map<LocalDate, MainStatisticsResponseDto> dtoMap = dtoList.stream()
.collect(Collectors.toMap(MainStatisticsResponseDto::getDate, dto -> dto));
// 모든 날짜에 대해 데이터가 없으면 기본값 생성
List<MainStatisticsResponseDto> fullDtoList = allDates.stream()
.map(date -> dtoMap.getOrDefault(date, MainStatisticsResponseDto.createWithDefaults(date)))
.toList();
return MainStatisticsResponseListDto.builder()
.data(fullDtoList)
.build();
}
}
② MainStatisticsResponseDto : 전달하려는 데이터 빌드 & 기본값 설정
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MainStatisticsResponseDto {
private LocalDate date;
private int carbohydrate;
private int protein;
private int fat;
private int kcal;
public static List<MainStatisticsResponseDto> mainStatisticsResponse(List<Food> foodList) {
return foodList.stream()
.map(m -> MainStatisticsResponseDto.builder()
.date(m.getCreatedAt())
.carbohydrate(m.getCarbohydrate())
.protein(m.getProtein())
.fat(m.getFat())
.kcal((m.getCarbohydrate() * 4) + (m.getProtein() * 4) + (m.getFat() * 9))
.build())
.collect(Collectors.toList());
}
public static MainStatisticsResponseDto createWithDefaults(LocalDate date) {
return MainStatisticsResponseDto.builder()
.date(date)
.carbohydrate(0)
.protein(0)
.fat(0)
.kcal(0)
.build();
}
}
③ MainController : 파라미터로 시작일과 종료일을 받아 해당 날짜에 해당하는 데이터를 전달할 수 있도록 한다
@RestController
@RequiredArgsConstructor
@RequestMapping("/main")
public class MainController {
private final MainService mainService;
@GetMapping("/statistics") // 통계 조회
public ApiResponse<MainStatisticsResponseListDto> getStatistics(@RequestHeader("Authorization") String token,
@RequestParam("startDate") String startDate,
@RequestParam("endDate") String endDate) {
return ApiResponse.onSuccess(mainService.getStatistics(extractUserEmail(token), startDate, endDate));
}
public String extractUserEmail(String token) {
String jwtToken = token.substring(7);
String userEmail = JwtUtil.getEmail(jwtToken);
return userEmail;
}
}
④ MainServiceImpl
L String 으로 받은 날짜를 LocalDate 로 변환해주어야 한다
@Service
@Transactional
@RequiredArgsConstructor
public class MainServiceImpl implements MainService {
private final UserRepository userRepository;
private final FoodRepository foodRepository;
@Override
public MainStatisticsResponseListDto getStatistics(String userEmail, String startDate, String endDate) {
// 사용자 존재 여부 확인
User user = checkUser(userEmail);
// 날짜 변환
LocalDate startLocalDate = LocalDate.parse(startDate);
LocalDate endLocalDate = LocalDate.parse(endDate);
// 사용자 - 날짜에 해당하는 음식 통계 조회
List<Food> foodList = foodRepository.findAllByUserAndCreatedAtBetween(user, startLocalDate, endLocalDate);
List<MainStatisticsResponseDto> dtoList = MainStatisticsResponseDto.mainStatisticsResponse(foodList);
// 시작 날짜부터 끝 날짜까지 모든 날짜 리스트 생성
List<LocalDate> allDates = startLocalDate.datesUntil(endLocalDate.plusDays(1)).toList();
return MainStatisticsResponseListDto.mainStatisticsResponseList(dtoList, allDates);
}
public User checkUser(String userEmail) {
return userRepository.findByEmail(userEmail)
.orElseThrow(() -> new GeneralException(ErrorStatus.MEMBER_NOT_FOUND));
}
}
2024.09.03 - [Spring/[P] AI 기반 사용자 맞춤형 메뉴와 맛집 추천] - [Springboot] 식사 통계 조회 설계하기
[Springboot] 식사 통계 조회 설계하기
📂 /main L 기록 조회 L 기록 등록 L 통계 조회 ⬅️⬅️⬅️ 🔧 디자인 🔧 필요한 데이터 L 조회하는 날짜 기간 (시작 날짜 & 끝 날짜) 🔧 HTTP Method L GET🔧 API Path L /main/statistics?st
alsrudalsrudalsrud.tistory.com
'Spring > [P] AI 기반 사용자 맞춤형 메뉴와 맛집 추천' 카테고리의 다른 글
[SpringBoot/Jython] SpringBoot 에서 Python 사용하기 (0) | 2024.09.12 |
---|---|
[Springboot] 식사 통계 조회 설계하기 (0) | 2024.09.03 |
[Springboot] 식사 기록 등록 개발하기 - entity, enums (6) | 2024.09.02 |
[Springboot] 식사 기록 등록 개발하기 - controller, service, dto (0) | 2024.08.30 |
[Springboot] 식사 기록 등록 설계하기 (0) | 2024.08.29 |