From 2692414e978bcfb6b63e8c2c2707dcbc3a6c6515 Mon Sep 17 00:00:00 2001 From: Jeyong Date: Wed, 26 Mar 2025 13:29:16 +0900 Subject: [PATCH 1/2] =?UTF-8?q?{refactor}=20=EB=AA=A9=ED=91=9C=20=EC=9D=B8?= =?UTF-8?q?=EC=A6=9D=20=EC=99=84=EB=A3=8C=20=EC=9A=94=EC=B2=AD=EB=A7=8C=20?= =?UTF-8?q?=EC=88=98=ED=96=89=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Record/controller/RecordController.java | 13 +- .../dto/request/recordEndRequestDto.java | 6 + .../dto/request/recordStartRequestDto.java | 17 --- .../dto/response/recordStartResponseDto.java | 16 -- .../response/recordSummaryResponseDto.java | 6 + .../domain/Record/service/RecordService.java | 140 +++++++----------- 6 files changed, 71 insertions(+), 127 deletions(-) delete mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordStartRequestDto.java delete mode 100644 MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordStartResponseDto.java diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java index f536389..7e9478d 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/controller/RecordController.java @@ -1,7 +1,6 @@ package MathCaptain.weakness.domain.Record.controller; import MathCaptain.weakness.domain.Record.dto.request.recordEndRequestDto; -import MathCaptain.weakness.domain.Record.dto.response.recordStartResponseDto; import MathCaptain.weakness.domain.Record.dto.response.recordSummaryResponseDto; import MathCaptain.weakness.domain.Record.service.RecordService; import MathCaptain.weakness.domain.User.entity.Users; @@ -17,14 +16,8 @@ public class RecordController { private final RecordService recordService; - @PostMapping("/start/{groupId}") - public ApiResponse startRecord(@LoginUser Users loginUser, @PathVariable Long groupId) { - recordStartResponseDto startResponse = recordService.startRecord(loginUser, groupId); - return ApiResponse.ok(startResponse); - } - - @PostMapping("/end/{recordId}") - public ApiResponse endActivity(@PathVariable Long recordId, @RequestBody recordEndRequestDto requestDto) { - return ApiResponse.ok(recordService.endActivity(recordId, requestDto)); + @PostMapping("/end/{groupId}") + public ApiResponse endActivity(@LoginUser Users loginUser, @PathVariable Long groupId, @RequestBody recordEndRequestDto requestDto) { + return ApiResponse.ok(recordService.endActivity(loginUser, groupId, requestDto)); } } diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequestDto.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequestDto.java index 7f3c06f..292ea28 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequestDto.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordEndRequestDto.java @@ -5,6 +5,8 @@ import lombok.Data; import lombok.NoArgsConstructor; +import java.time.LocalDateTime; + @Data @Builder @NoArgsConstructor @@ -14,4 +16,8 @@ public class recordEndRequestDto { // 수행 시간 (분) private Long activityTime; + private LocalDateTime startTime; + + private LocalDateTime endTime; + } diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordStartRequestDto.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordStartRequestDto.java deleted file mode 100644 index 7dc5a0f..0000000 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/request/recordStartRequestDto.java +++ /dev/null @@ -1,17 +0,0 @@ -package MathCaptain.weakness.domain.Record.dto.request; - -import jakarta.validation.constraints.NotNull; -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class recordStartRequestDto { - - @NotNull - private Long userId; - - @NotNull - private Long groupId; - -} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordStartResponseDto.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordStartResponseDto.java deleted file mode 100644 index 1dd59b7..0000000 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordStartResponseDto.java +++ /dev/null @@ -1,16 +0,0 @@ -package MathCaptain.weakness.domain.Record.dto.response; - -import lombok.Builder; -import lombok.Data; - -@Data -@Builder -public class recordStartResponseDto { - - private Long recordId; - - private Long userDailyGoal; - - private Long remainingDailyGoal; - -} diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordSummaryResponseDto.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordSummaryResponseDto.java index f36039a..2060923 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordSummaryResponseDto.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/dto/response/recordSummaryResponseDto.java @@ -29,4 +29,10 @@ public class recordSummaryResponseDto { // 주간 목표 달성까지 남은 일 수 (일) (달성시 0) private int remainingWeeklyGoalDays; + + // 사용자가 설정한 일간 목표 + private int personalDailyGoal; + + // 사용자가 설정한 주간 목표 + private int personalWeeklyGoal; } diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java index 6dd40de..8138bfd 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Record/service/RecordService.java @@ -2,11 +2,9 @@ import MathCaptain.weakness.domain.Group.entity.Group; import MathCaptain.weakness.domain.Group.entity.RelationBetweenUserAndGroup; -import MathCaptain.weakness.domain.Group.repository.GroupRepository; import MathCaptain.weakness.domain.Group.repository.RelationRepository; import MathCaptain.weakness.domain.Record.entity.ActivityRecord; import MathCaptain.weakness.domain.Record.dto.request.recordEndRequestDto; -import MathCaptain.weakness.domain.Record.dto.response.recordStartResponseDto; import MathCaptain.weakness.domain.Record.dto.response.recordSummaryResponseDto; import MathCaptain.weakness.domain.Record.repository.RecordRepository; import MathCaptain.weakness.domain.User.entity.Users; @@ -33,80 +31,31 @@ public class RecordService { private final RecordRepository recordRepository; private final RelationRepository relationRepository; - private final GroupRepository groupRepository; /// 기록 - // 기록 시작 - public recordStartResponseDto startRecord(Users user, Long groupId) { + // 기록 저장 + public recordSummaryResponseDto endActivity(Users user, Long groupId, recordEndRequestDto endRequest) { // 사용자 식별 RelationBetweenUserAndGroup relation = relationRepository.findByMemberAndGroup_Id(user, groupId) .orElseThrow(() -> new IllegalArgumentException("해당 관계가 존재하지 않습니다.")); - // 기존 미완료된 기록이 있는지 확인 - checkRemainRecord(user, relation.getGroup()); + ActivityRecord record = buildRecord(user, relation, endRequest); - ActivityRecord record = buildRecord(user, relation); - - Long recordId = recordRepository.save(record).getId(); - - return buildRecordStartResponse(recordId, relation); - } - - // 기록 종료 - public recordSummaryResponseDto endActivity(Long recordId, recordEndRequestDto endRequest) { - - // 진행 중인 활동 찾기 - ActivityRecord record = recordRepository.findById(recordId) - .orElseThrow(() -> new IllegalArgumentException("현재 진행중인 인증이 존재하지 않습니다.")); - - // 사용자 식별 - Users user = record.getUser(); - Group group = record.getGroup(); - - RelationBetweenUserAndGroup relation = relationRepository.findByMemberAndGroup(user,group) - .orElseThrow(() -> new IllegalArgumentException("해당 그룹에 속하지 않은 사용자입니다.")); - - // 활동 기록 업데이트 - updateRecord(record, relation, endRequest); - - // 일간 목표 시간 달성시 - if (isDailyGoalAchieved(relation)) { - // 일간 목표 달성 성공 업데이트 (기록) - record.updateDailyGoalAchieved(true); - - // 그룹의 요일 목표 수행 카운트 증가 (그룹) - increaseWeeklyGoalAchieveCount(relation, record); - - // 일간 목표 달성 포인트 획득 - addPoint(user, group, DAILY_GOAL_ACHIEVE); - - // 주간 목표 + 1 (일간 목표 충족시 업데이트) - relation.updatePersonalWeeklyGoalAchieved(relation.getPersonalWeeklyGoalAchieve() + 1); - } - - // 주간 목표 달성시 - if (isWeeklyGoalAchieved(relation)) { - // 주간 목표 달성 성공 업데이트 (기록) - record.updateWeeklyGoalAchieved(true); - - // 주간 목표 달성 스트릭 업데이트 (관계) - relation.updateWeeklyGoalAchieveStreak(relation.getWeeklyGoalAchieveStreak() + 1); - - // 주간 목표 달성 포인트 계산 - Long weeklyAchievePoint = WEEKLY_GOAL_ACHIEVE_BASE * (relation.getWeeklyGoalAchieveStreak() + relation.getPersonalWeeklyGoal()); + // 그룹 식별 + Group group = relation.getGroup(); - // 주간 목표 달성 포인트 획득 - addPoint(user, group, weeklyAchievePoint); - } + // 목표에 수행 결과 빈영 + updateGoalAchieve(user, relation, record, group); recordRepository.save(record); - return buildRecordSummaryResponseDto(record, calculateRemainingDailyGoalMinutes(relation), calculateRemainingWeeklyGoal(relation)); + return buildRecordSummaryResponseDto(record, relation, calculateRemainingDailyGoalMinutes(relation), calculateRemainingWeeklyGoal(relation)); } // 주간 목표 달성 여부 조회 + public Map getWeeklyGoalStatus(Users user, Group group, LocalDateTime weekStart) { // 주의 시작과 끝 계산 (월요일 ~ 다음 주 월요일) LocalDateTime startOfWeek = calculateStartOfWeek(weekStart); @@ -118,7 +67,6 @@ public Map getWeeklyGoalStatus(Users user, Group group, Loca // 요일별 활동 기록 여부 맵 생성 return createWeeklyGoalStatusMap(activeDays); } - /// 로직 // 일간 목표 달성 여부 확인 @@ -131,13 +79,13 @@ private boolean isWeeklyGoalAchieved(RelationBetweenUserAndGroup relation) { } // 그룹의 요일 목표 수행 카운트 증가 + public void increaseWeeklyGoalAchieveCount(RelationBetweenUserAndGroup relation, ActivityRecord record) { // 활동 요일 DayOfWeek dayOfWeek = record.getDayOfWeek(); Group group = relation.getGroup(); group.increaseWeeklyGoalAchieveMap(dayOfWeek); } - private void addPoint(Users user, Group group, Long point) { // 개인 포인트 획득 (일간 목표 달성) user.addPoint(point); @@ -146,6 +94,44 @@ private void addPoint(Users user, Group group, Long point) { group.addPoint(point); } + private void updateGoalAchieve(Users user, RelationBetweenUserAndGroup relation, ActivityRecord record, Group group) { + + // 일간 달성 시간 업데이트 (분) + relation.updatePersonalDailyGoalAchieved( + Optional.ofNullable(relation.getPersonalDailyGoalAchieve()) + .orElse(0L) + record.getDurationInMinutes()); + + // 일간 목표 시간 달성시 + if (isDailyGoalAchieved(relation)) { + // 일간 목표 달성 성공 업데이트 (기록) + record.updateDailyGoalAchieved(true); + + // 그룹의 요일 목표 수행 카운트 증가 (그룹) + increaseWeeklyGoalAchieveCount(relation, record); + + // 일간 목표 달성 포인트 획득 + addPoint(user, group, DAILY_GOAL_ACHIEVE); + + // 주간 목표 + 1 (일간 목표 충족시 업데이트) + relation.updatePersonalWeeklyGoalAchieved(relation.getPersonalWeeklyGoalAchieve() + 1); + } + + // 주간 목표 달성시 + if (isWeeklyGoalAchieved(relation)) { + // 주간 목표 달성 성공 업데이트 (기록) + record.updateWeeklyGoalAchieved(true); + + // 주간 목표 달성 스트릭 업데이트 (관계) + relation.updateWeeklyGoalAchieveStreak(relation.getWeeklyGoalAchieveStreak() + 1); + + // 주간 목표 달성 포인트 계산 + Long weeklyAchievePoint = WEEKLY_GOAL_ACHIEVE_BASE * (relation.getWeeklyGoalAchieveStreak() + relation.getPersonalWeeklyGoal()); + + // 주간 목표 달성 포인트 획득 + addPoint(user, group, weeklyAchievePoint); + } + } + private LocalDateTime calculateStartOfWeek(LocalDateTime weekStart) { return weekStart.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); } @@ -172,17 +158,6 @@ private void checkRemainRecord(Users user, Group group) { } } - private void updateRecord(ActivityRecord record, RelationBetweenUserAndGroup relation, recordEndRequestDto endRequest) { - record.updateEndTime(LocalDateTime.now()); - record.updateDurationInMinutes(endRequest.getActivityTime()); - record.updateDayOfWeek(LocalDateTime.now().getDayOfWeek()); - - // 일간 달성 시간 업데이트 (분) - relation.updatePersonalDailyGoalAchieved( - Optional.ofNullable(relation.getPersonalDailyGoalAchieve()) - .orElse(0L) + record.getDurationInMinutes()); - } - private Long calculateRemainingDailyGoalMinutes(RelationBetweenUserAndGroup relation) { return Math.max(relation.getPersonalDailyGoal() * 60L - relation.getPersonalDailyGoalAchieve(), 0L); } @@ -193,7 +168,7 @@ private int calculateRemainingWeeklyGoal(RelationBetweenUserAndGroup relation) { /// 빌더 - private recordSummaryResponseDto buildRecordSummaryResponseDto(ActivityRecord activityRecord, Long remainingDailyGoalMinutes, int remainingWeeklyGoal) { + private recordSummaryResponseDto buildRecordSummaryResponseDto(ActivityRecord activityRecord, RelationBetweenUserAndGroup relation, Long remainingDailyGoalMinutes, int remainingWeeklyGoal) { return recordSummaryResponseDto.builder() .userName(activityRecord.getUser().getName()) .groupName(activityRecord.getGroup().getName()) @@ -202,22 +177,19 @@ private recordSummaryResponseDto buildRecordSummaryResponseDto(ActivityRecord ac .weeklyGoalAchieved(activityRecord.isWeeklyGoalAchieved()) .remainingDailyGoalMinutes(remainingDailyGoalMinutes) .remainingWeeklyGoalDays(remainingWeeklyGoal) + .personalDailyGoal(relation.getPersonalDailyGoal()) + .personalWeeklyGoal(relation.getPersonalWeeklyGoal()) .build(); } - private recordStartResponseDto buildRecordStartResponse(Long recordId, RelationBetweenUserAndGroup relation) { - return recordStartResponseDto.builder() - .recordId(recordId) - .userDailyGoal(relation.getPersonalDailyGoal() * 60L) - .remainingDailyGoal(calculateRemainingDailyGoalMinutes(relation)) - .build(); - } - - private static ActivityRecord buildRecord(Users user, RelationBetweenUserAndGroup relation) { + private static ActivityRecord buildRecord(Users user, RelationBetweenUserAndGroup relation, recordEndRequestDto endRequest) { return ActivityRecord.builder() .user(user) .group(relation.getGroup()) - .startTime(LocalDateTime.now()) + .startTime(endRequest.getStartTime()) + .endTime(endRequest.getEndTime()) + .durationInMinutes(endRequest.getActivityTime()) + .dayOfWeek(LocalDateTime.now().getDayOfWeek()) .build(); } } From aa003bcf4d13ecf84d64bdb7e53dcc16e04d05b1 Mon Sep 17 00:00:00 2001 From: Jeyong Date: Wed, 26 Mar 2025 13:29:43 +0900 Subject: [PATCH 2/2] =?UTF-8?q?{fix}=20=EB=88=84=EB=9D=BD=EB=90=9C=20?= =?UTF-8?q?=EC=95=A0=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/Group/entity/RelationBetweenUserAndGroup.java | 7 ++++--- .../MathCaptain/weakness/domain/User/entity/Users.java | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/RelationBetweenUserAndGroup.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/RelationBetweenUserAndGroup.java index 3d1a2e6..3adc87a 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/RelationBetweenUserAndGroup.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/Group/entity/RelationBetweenUserAndGroup.java @@ -6,6 +6,8 @@ import jakarta.persistence.*; import lombok.*; import org.hibernate.validator.constraints.Range; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDate; @@ -15,6 +17,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @AllArgsConstructor @Table(name = "RELATION_BETWEEN_USER_AND_GROUP") +@EntityListeners(AuditingEntityListener.class) public class RelationBetweenUserAndGroup { @Id @@ -35,6 +38,7 @@ public class RelationBetweenUserAndGroup { private GroupRole groupRole; @Column(nullable = false) + @CreatedDate private LocalDate joinDate; private RequestStatus requestStatus; @@ -66,9 +70,6 @@ protected void onPrePersist() { if (this.groupRole == null) { this.groupRole = GroupRole.MEMBER; // 기본값 설정 } - if (this.joinDate == null) { - this.joinDate = LocalDate.now(); // joinDate의 기본값 설정 (필요 시) - } this.requestStatus = RequestStatus.WAITING; diff --git a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/entity/Users.java b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/entity/Users.java index ecd111a..50b8819 100644 --- a/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/entity/Users.java +++ b/MathCaptain/weakness/src/main/java/MathCaptain/weakness/domain/User/entity/Users.java @@ -48,6 +48,7 @@ public class Users { @OneToMany(mappedBy = "author") private List recruitment; + @Enumerated(value = EnumType.STRING) private Tiers tier; //== jwt 토큰 추가 ==//