Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public SuccessResponse<RecordResponse> createRecord(
@RequestParam int totalTime,
@LoginUser String email) {


RecordResponse response = recordService.createRecord(routineId, totalTime, email);
return SuccessResponse.ok(response);
}
Expand All @@ -37,4 +36,4 @@ public SuccessResponse<List<RecordResponse>> getRecordsByDate(
return SuccessResponse.ok(response);
}

}
}
Original file line number Diff line number Diff line change
@@ -1,83 +1,116 @@
package com.project.cloud.domain.record.service;

import com.project.cloud.domain.exercise.enumerate.Target;
import com.project.cloud.domain.record.dto.RecordResponse;
import com.project.cloud.domain.record.entity.Record;
import com.project.cloud.domain.record.repository.RecordRepository;
import com.project.cloud.domain.routine.entity.Routine;
import com.project.cloud.domain.routine.repository.RoutineRepository;
import com.project.cloud.domain.routineItem.entity.RoutineItem;
import com.project.cloud.domain.user.entity.User;
import com.project.cloud.domain.user.repository.UserRepository;
import com.project.cloud.domain.userBodyPart.entity.UserBodyPart;
import com.project.cloud.global.exception.CustomException;
import com.project.cloud.global.exception.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.List;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
@RequiredArgsConstructor
public class RecordService {

private final ApplicationEventPublisher applicationEventPublisher;
private final RecordRepository recordRepository;
private final RoutineRepository routineRepository;
private final UserRepository userRepository;


@Transactional
public RecordResponse createRecord(Long routineId, int totalTime, String email){
public RecordResponse createRecord(Long routineId, int totalTime, String email) {
User user = findUserByEmail(email);
Routine routine = routineRepository.findById(routineId)
.orElseThrow(() -> new CustomException(ErrorCode.ROUTINE_NOT_FOUND));
.orElseThrow(() -> new CustomException(ErrorCode.ROUTINE_NOT_FOUND));

if (!routine.getUser().getId().equals(user.getId())) {
throw new CustomException(ErrorCode.ROUTINE_FORBIDDEN);
}

saveExperience(user, routine);

LocalDate today = LocalDate.now();

Optional<Record> optinalRecord = recordRepository.findByUserAndRoutineAndDate(user, routine, today);
Record record;
if (optinalRecord.isPresent()){
if (optinalRecord.isPresent()) {
record = optinalRecord.get();
int updateTime = record.getTotalTime() + totalTime;
record.updateTotalTime(updateTime);
}
else {
} else {
record = Record.create(user, routine, LocalDate.now(), totalTime);
recordRepository.save(record);
}


return new RecordResponse(
record.getId(),
routine.getId(),
routine.getName(),
record.getDate(),
record.getTotalTime()
record.getId(),
routine.getId(),
routine.getName(),
record.getDate(),
record.getTotalTime()
);
}

@Transactional(readOnly= true)
private void saveExperience(User user, Routine routine) {
for (RoutineItem item : routine.getItems()) {
saveUserBodyExperience(user, item);
}
}

private void saveUserBodyExperience(User user, RoutineItem item) {
UserBodyPart userBodyPart = findUserBodyPartByTarget(user.getBodyPartStats(),
item.getExercise().getTarget());
int exp = calculateExp(item);
userBodyPart.saveExperience(exp);
user.saveExperience(exp);
}

private UserBodyPart findUserBodyPartByTarget(List<UserBodyPart> bodyPartStats, Target target) {
for (UserBodyPart bodyPartStat : bodyPartStats) {
String bodyPartName = bodyPartStat.getBodyPart().getName();
if (bodyPartName.equals(target.name())) {
return bodyPartStat;
}
}
throw new CustomException(ErrorCode.BODYPART_NOT_FOUND);
}

private int calculateExp(RoutineItem item) {
return item.getSetCount() * item.getRepeatCount();
}


@Transactional(readOnly = true)
public List<RecordResponse> getRecordsByDate(String email, LocalDate date) {
User user = findUserByEmail(email);
List<Record> records = recordRepository.findAllByUserAndDate(user, date);
return records.stream()
.map(this::toRecordResponse)
.toList();
.map(this::toRecordResponse)
.toList();
}


private RecordResponse toRecordResponse(Record record) {
return new RecordResponse(
record.getId(),
record.getRoutine().getId(),
record.getRoutine().getName(),
record.getDate(),
record.getTotalTime()
record.getId(),
record.getRoutine().getId(),
record.getRoutine().getName(),
record.getDate(),
record.getTotalTime()
);
}

Expand Down
10 changes: 10 additions & 0 deletions cloud/src/main/java/com/project/cloud/domain/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,14 @@ public void updateBodyParts(List<UserBodyPart> parts) {
this.bodyPartStats.clear();
this.bodyPartStats.addAll(parts);
}

public void saveExperience(int exp) {
while (this.exp >= 300 && this.level < 5) {
this.level++;
this.exp -= 300;
}
if (this.level == 5) {
this.exp = 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.project.cloud.domain.bodyPart.entity.BodyPart;
import com.project.cloud.domain.bodyPart.repository.BodyPartRepository;
import com.project.cloud.domain.exercise.enumerate.Target;
import com.project.cloud.domain.record.entity.Record;
import com.project.cloud.domain.user.dto.BodyPartExpResponse;
import com.project.cloud.domain.user.dto.DailyDurationResponse;
Expand Down Expand Up @@ -90,21 +91,20 @@ public UserCharacterResponse getUserCharacterInfo(String email) {
makeBodyPartResponse(user.getBodyPartStats()));
}

// TODO : bodyPart Enum 작성 필요
private BodyPartExpResponse makeBodyPartResponse(List<UserBodyPart> bodyParts) {
return new BodyPartExpResponse(
findBodyPartExpByName(bodyParts, "chest"),
findBodyPartExpByName(bodyParts, "back"),
findBodyPartExpByName(bodyParts, "legs"),
findBodyPartExpByName(bodyParts, "abs"),
findBodyPartExpByName(bodyParts, "shoulders")
findBodyPartExpByName(bodyParts, Target.CHEST),
findBodyPartExpByName(bodyParts, Target.BACK),
findBodyPartExpByName(bodyParts, Target.LEGS),
findBodyPartExpByName(bodyParts, Target.CORE),
findBodyPartExpByName(bodyParts, Target.SHOULDERS)
);
}

// TODO : N+1 없애기
private int findBodyPartExpByName(List<UserBodyPart> bodyParts, String partName) {
private int findBodyPartExpByName(List<UserBodyPart> bodyParts, Target target
) {
Optional<UserBodyPart> part = bodyParts.stream()
.filter(userBodyPart -> userBodyPart.getBodyPart().getName().equals(partName))
.filter(userBodyPart -> userBodyPart.getBodyPart().getName().equals(target.name()))
.findFirst();
if (part.isEmpty()) {
throw new CustomException(ErrorCode.BODYPART_NOT_FOUND);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,8 @@ public UserBodyPart(User user, BodyPart bodyPart, int exp) {
public static UserBodyPart create(User user, BodyPart bodyPart, int exp) {
return new UserBodyPart(user, bodyPart, exp);
}

public void saveExperience(int exp){
this.exp += exp;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.project.cloud.domain.bodyPart.entity.BodyPart;
import com.project.cloud.domain.record.entity.Record;
import com.project.cloud.domain.bodyPart.repository.BodyPartRepository;
import com.project.cloud.domain.routine.entity.Routine;
import com.project.cloud.domain.user.dto.BodyPartExpResponse;
import com.project.cloud.domain.user.dto.DailyDurationResponse;
import com.project.cloud.domain.user.dto.UserCharacterResponse;
Expand Down Expand Up @@ -126,42 +127,4 @@ void setUp() {
assertThat(exp.abs()).isEqualTo(10);
assertThat(exp.shoulders()).isEqualTo(10);
}

@Test
void getUserStatistics_이번달_운동기록_정상조회() {
// given
LocalDate today = LocalDate.now();
LocalDate earlierThisMonth = today.withDayOfMonth(1).plusDays(1);
LocalDate notThisMonth = today.minusMonths(1).withDayOfMonth(10);

Record record1 = Record.create(user, earlierThisMonth, 30);
Record record2 = Record.create(user, today, 60);

Record oldRecord = Record.create(user, notThisMonth, 45);

user.getRecords().addAll(List.of(record1, record2, oldRecord));

// when
UserExerciseStatisticsResponse response = userService.getUserStatistics(email);

// then
assertThat(response.todayDuration()).isEqualTo(60);

int expectedAverage = (30 + 60) / today.lengthOfMonth();
assertThat(response.averageDuration()).isEqualTo(expectedAverage);

assertThat(response.dailyDurationResponses()).hasSize(today.lengthOfMonth());

DailyDurationResponse todayResponse = response.dailyDurationResponses().stream()
.filter(d -> d.date().equals(today))
.findFirst()
.orElseThrow();

assertThat(todayResponse.duration()).isEqualTo(60);

boolean containsOld = response.dailyDurationResponses().stream()
.anyMatch(d -> d.date().equals(notThisMonth));
assertThat(containsOld).isFalse();
}

}
Loading