Skip to content

Commit

Permalink
feat(Record): 업적 API 추가
Browse files Browse the repository at this point in the history
  • Loading branch information
limehee committed Sep 26, 2024
1 parent 954036e commit 01bcd21
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.stempo.api.domain.presentation.dto.request.RecordRequestDto;
import com.stempo.api.domain.presentation.dto.response.RecordResponseDto;
import com.stempo.api.domain.presentation.dto.response.RecordStatisticsResponseDto;

import java.time.LocalDate;
import java.util.List;
Expand All @@ -11,4 +12,6 @@ public interface RecordService {
String record(RecordRequestDto requestDto);

List<RecordResponseDto> getRecordsByDateRange(LocalDate startDate, LocalDate endDate);

RecordStatisticsResponseDto getRecordStatistics();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
import com.stempo.api.domain.domain.repository.RecordRepository;
import com.stempo.api.domain.presentation.dto.request.RecordRequestDto;
import com.stempo.api.domain.presentation.dto.response.RecordResponseDto;
import com.stempo.api.domain.presentation.dto.response.RecordStatisticsResponseDto;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;

Expand Down Expand Up @@ -56,4 +59,50 @@ public List<RecordResponseDto> getRecordsByDateRange(LocalDate startDate, LocalD
}
return combinedRecords;
}

@Override
@Transactional(readOnly = true)
public RecordStatisticsResponseDto getRecordStatistics() {
String deviceTag = userService.getCurrentDeviceTag();

LocalDateTime todayStartDateTime = LocalDate.now().atStartOfDay();
LocalDateTime todayEndDateTime = todayStartDateTime.plusDays(1);
LocalDateTime weekStartDateTime = LocalDate.now()
.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY))
.atStartOfDay();

// 오늘의 훈련 횟수 계산
int todayWalkTrainingCount = recordRepository.countByDeviceTagAndCreatedAtBetween(
deviceTag, todayStartDateTime, todayEndDateTime);

// 이번 주 훈련 횟수 계산 (월요일부터 오늘까지)
int weeklyWalkTrainingCount = recordRepository.countByDeviceTagAndCreatedAtBetween(
deviceTag, weekStartDateTime, todayEndDateTime);

// 연속된 훈련 일수 계산
int consecutiveWalkTrainingDays = calculateConsecutiveTrainingDays(deviceTag);

return RecordStatisticsResponseDto.of(todayWalkTrainingCount, weeklyWalkTrainingCount, consecutiveWalkTrainingDays);
}

private int calculateConsecutiveTrainingDays(String deviceTag) {
List<LocalDateTime> createdDates = recordRepository.findCreatedAtByDeviceTagOrderByCreatedAtDesc(deviceTag);
int consecutiveDays = 0;
LocalDate previousDate = null;

for (LocalDateTime createdAt : createdDates) {
LocalDate recordDate = createdAt.toLocalDate();

// 첫 기록이거나, 이전 기록이 하루 전날이면 연속으로 카운트
if (previousDate == null || previousDate.minusDays(1).isEqual(recordDate)) {
consecutiveDays++;
previousDate = recordDate;
} else {
// 연속된 날짜가 아니면 중단
break;
}
}
return consecutiveDays;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ public interface RecordRepository {
Record findLatestBeforeStartDate(String deviceTag, LocalDateTime startDateTime);

List<Record> findByDeviceTag(String deviceTag);

List<LocalDateTime> findCreatedAtByDeviceTagOrderByCreatedAtDesc(String deviceTag);

int countByDeviceTagAndCreatedAtBetween(String deviceTag, LocalDateTime startDateTime, LocalDateTime endDateTime);
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,14 @@ Optional<RecordEntity> findLatestBeforeStartDate(
);

List<RecordEntity> findByDeviceTag(String deviceTag);

@Query("SELECT r.createdAt " +
"FROM RecordEntity r " +
"WHERE r.deviceTag = :deviceTag " +
"ORDER BY r.createdAt DESC")
List<LocalDateTime> findCreatedAtByDeviceTagOrderByCreatedAtDesc(
@Param("deviceTag") String deviceTag
);

int countByDeviceTagAndCreatedAtBetween(String deviceTag, LocalDateTime startDateTime, LocalDateTime endDateTime);
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,14 @@ public List<Record> findByDeviceTag(String deviceTag) {
.map(mapper::toDomain)
.toList();
}

@Override
public List<LocalDateTime> findCreatedAtByDeviceTagOrderByCreatedAtDesc(String deviceTag) {
return repository.findCreatedAtByDeviceTagOrderByCreatedAtDesc(deviceTag);
}

@Override
public int countByDeviceTagAndCreatedAtBetween(String deviceTag, LocalDateTime startDateTime, LocalDateTime endDateTime) {
return repository.countByDeviceTagAndCreatedAtBetween(deviceTag, startDateTime, endDateTime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.stempo.api.domain.application.service.RecordService;
import com.stempo.api.domain.presentation.dto.request.RecordRequestDto;
import com.stempo.api.domain.presentation.dto.response.RecordResponseDto;
import com.stempo.api.domain.presentation.dto.response.RecordStatisticsResponseDto;
import com.stempo.api.global.dto.ApiResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand Down Expand Up @@ -48,4 +49,12 @@ public ApiResponse<List<RecordResponseDto>> getRecords(
List<RecordResponseDto> records = recordService.getRecordsByDateRange(startDate, endDate);
return ApiResponse.success(records);
}

@Operation(summary = "[U] 내 재활 운동 기록 통계" , description = "ROLE_USER 이상의 권한이 필요함")
@Secured({ "ROLE_USER", "ROLE_ADMIN" })
@GetMapping("/api/v1/records/statistics")
public ApiResponse<RecordStatisticsResponseDto> getRecordStatistics() {
RecordStatisticsResponseDto statistics = recordService.getRecordStatistics();
return ApiResponse.success(statistics);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.stempo.api.domain.presentation.dto.response;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class RecordStatisticsResponseDto {

private int todayWalkTrainingCount;
private int weeklyWalkTrainingCount;
private int consecutiveWalkTrainingDays;

public static RecordStatisticsResponseDto of(int todayWalkTrainingCount, int weeklyWalkTrainingCount, int consecutiveWalkTrainingDays) {
return RecordStatisticsResponseDto.builder()
.todayWalkTrainingCount(todayWalkTrainingCount)
.weeklyWalkTrainingCount(weeklyWalkTrainingCount)
.consecutiveWalkTrainingDays(consecutiveWalkTrainingDays)
.build();
}
}

0 comments on commit 01bcd21

Please sign in to comment.