Skip to content

Commit c557eeb

Browse files
authored
[Feature] 마이페이지 기능 구현
[Feature] 마이페이지 기능 구현
2 parents c16cc7a + 0902dc1 commit c557eeb

File tree

15 files changed

+442
-4
lines changed

15 files changed

+442
-4
lines changed

src/main/java/com/cmc/mercury/domain/memo/service/MemoService.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
import com.cmc.mercury.domain.memo.dto.MemoUpdateRequest;
66
import com.cmc.mercury.domain.memo.entity.Memo;
77
import com.cmc.mercury.domain.memo.repository.MemoRepository;
8+
import com.cmc.mercury.domain.mypage.entity.HabitHistory;
9+
import com.cmc.mercury.domain.mypage.repository.HabitHistoryRepository;
10+
import com.cmc.mercury.domain.mypage.service.MyPageService;
811
import com.cmc.mercury.domain.record.entity.Record;
912
import com.cmc.mercury.domain.record.entity.RecordDetail;
1013
import com.cmc.mercury.domain.record.repository.RecordRepository;
@@ -17,6 +20,7 @@
1720
import org.springframework.stereotype.Service;
1821
import org.springframework.transaction.annotation.Transactional;
1922

23+
import java.time.LocalDate;
2024
import java.time.LocalDateTime;
2125

2226
@Service
@@ -30,7 +34,8 @@ public class MemoService {
3034

3135
private final MemoRepository memoRepository;
3236
private final RecordRepository recordRepository;
33-
private final UserService userService;
37+
private final HabitHistoryRepository habitHistoryRepository;
38+
private final MyPageService myPageService;
3439

3540
@Transactional
3641
public MemoResponse createMemo(User user, Long recordId, MemoCreateRequest request) {
@@ -67,6 +72,12 @@ public MemoResponse createMemo(User user, Long recordId, MemoCreateRequest reque
6772
// 사용자 경험치 업데이트
6873
user.updateExp(user.getExp() + acquiredExp);
6974

75+
// 날짜별 습관쌓기 기록
76+
LocalDate date = LocalDate.now();
77+
HabitHistory history = myPageService.saveHabitHistoryIfNotExists(user.getId(), date, acquiredExp);
78+
history.updateHasRecord();
79+
habitHistoryRepository.save(history);
80+
7081
return MemoResponse.from(savedMemo, recordId);
7182
}
7283

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.cmc.mercury.domain.mypage.controller;
2+
3+
import com.cmc.mercury.domain.mypage.dto.HabitDetailResponse;
4+
import com.cmc.mercury.domain.mypage.dto.MyPageResponse;
5+
import com.cmc.mercury.domain.mypage.service.MyPageService;
6+
import com.cmc.mercury.domain.user.entity.User;
7+
import com.cmc.mercury.global.oauth.annotation.AuthUser;
8+
import io.swagger.v3.oas.annotations.Operation;
9+
import io.swagger.v3.oas.annotations.tags.Tag;
10+
import lombok.RequiredArgsConstructor;
11+
import org.springframework.format.annotation.DateTimeFormat;
12+
import org.springframework.http.ResponseEntity;
13+
import org.springframework.web.bind.annotation.GetMapping;
14+
import org.springframework.web.bind.annotation.RequestMapping;
15+
import org.springframework.web.bind.annotation.RequestParam;
16+
import org.springframework.web.bind.annotation.RestController;
17+
18+
import java.time.LocalDate;
19+
20+
@RestController
21+
@RequestMapping("/api/my-page")
22+
@RequiredArgsConstructor
23+
@Tag(name = "MyPageController", description = "마이페이지 관련 API")
24+
public class MyPageController {
25+
26+
private final MyPageService myPageService;
27+
28+
@GetMapping("")
29+
@Operation(summary = "마이페이지 조회", description = "마이페이지 메인 화면을 조회합니다.")
30+
public ResponseEntity<MyPageResponse> getMyPage(@AuthUser User user) {
31+
return ResponseEntity.ok(myPageService.getMyPage(user));
32+
}
33+
34+
@GetMapping("/history")
35+
@Operation(summary = "날짜별 습관쌓기 조회", description = "쿼리파라미터의 date 값은 YYYY-MM-DD 형식입니다.")
36+
public ResponseEntity<HabitDetailResponse> getHabitDetail(
37+
@AuthUser User user,
38+
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
39+
return ResponseEntity.ok(myPageService.getHabitDetail(user, date));
40+
}
41+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.cmc.mercury.domain.mypage.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
import jakarta.persistence.Column;
5+
6+
@Schema(title = "날짜별 습관쌓기 응답 형식")
7+
public record HabitDetailResponse(
8+
9+
@Schema(description = "날짜별 습관쌓기 ID")
10+
Long habitHistoryID,
11+
@Schema(description = "요일")
12+
String day,
13+
@Schema(description = "습관쌓기 연속 일수")
14+
int streakCount,
15+
@Schema(description = "획득한 경험치")
16+
int acquiredExp,
17+
@Schema(description = "독서기록 또는 메모 작성 여부")
18+
boolean hasRecord,
19+
@Schema(description = "타이머 완료 여부")
20+
boolean hasTimer
21+
) {
22+
23+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.cmc.mercury.domain.mypage.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
import java.util.List;
6+
7+
@Schema(title = "마이페이지 응답 형식")
8+
public record MyPageResponse(
9+
10+
@Schema(description = "습관쌓기 ID")
11+
Long habitID,
12+
@Schema(description = "가입 기간")
13+
int joinDays,
14+
@Schema(description = "사용자 닉네임")
15+
String nickname,
16+
@Schema(description = "사용자 경험치")
17+
int exp,
18+
@Schema(description = "습관쌓기 연속 일수")
19+
int streakDays,
20+
@Schema(description = "최근 7일 streak 정보")
21+
List<WeeklyStreakResponse> weeklyStreak
22+
// @Schema(description = "가장 최근 독서기록 ID")
23+
// Long latestRecordID
24+
) {
25+
26+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.cmc.mercury.domain.mypage.dto;
2+
3+
import io.swagger.v3.oas.annotations.media.Schema;
4+
5+
@Schema(title = "요일별 성공 여부")
6+
public record WeeklyStreakResponse(
7+
8+
@Schema(description = "요일")
9+
String day,
10+
@Schema(description = "성공 여부")
11+
boolean isSuccess
12+
) {
13+
14+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.cmc.mercury.domain.mypage.entity;
2+
3+
import com.cmc.mercury.domain.user.entity.User;
4+
import com.cmc.mercury.global.domain.BaseEntity;
5+
import jakarta.persistence.*;
6+
import lombok.AccessLevel;
7+
import lombok.Builder;
8+
import lombok.Getter;
9+
import lombok.RequiredArgsConstructor;
10+
11+
@Entity
12+
@Getter
13+
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
14+
public class Habit extends BaseEntity {
15+
16+
@Id
17+
@GeneratedValue(strategy = GenerationType.IDENTITY)
18+
@Column(name = "habit_id")
19+
private Long id;
20+
21+
@OneToOne(fetch = FetchType.LAZY)
22+
@JoinColumn(name = "user_id", nullable = false)
23+
private User user;
24+
25+
@Column(nullable = false)
26+
private int streakDays;
27+
28+
@Builder
29+
public Habit(User user, int streakDays) {
30+
this.user = user;
31+
this.streakDays = streakDays;
32+
}
33+
34+
public void updateStreakDays(int streakDays) {
35+
this.streakDays = streakDays;
36+
}
37+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.cmc.mercury.domain.mypage.entity;
2+
3+
import com.cmc.mercury.global.domain.BaseEntity;
4+
import jakarta.persistence.*;
5+
import lombok.AccessLevel;
6+
import lombok.Builder;
7+
import lombok.Getter;
8+
import lombok.RequiredArgsConstructor;
9+
10+
@Entity
11+
@Getter
12+
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
13+
public class HabitHistory extends BaseEntity {
14+
15+
@Id
16+
@GeneratedValue(strategy = GenerationType.IDENTITY)
17+
@Column(name = "habit_history_id")
18+
private Long id;
19+
20+
@ManyToOne(fetch = FetchType.LAZY)
21+
@JoinColumn(name = "habit_id")
22+
private Habit habit;
23+
24+
@Column(nullable = false)
25+
private boolean hasRecord = false;
26+
27+
@Column(nullable = false)
28+
private boolean hasTimer = false;
29+
30+
@Column(nullable = false)
31+
private int streakCount = 0;
32+
33+
@Column(nullable = false)
34+
private int acquiredExp = 0;
35+
36+
@Builder
37+
public HabitHistory(Habit habit, Integer streakCount, Integer acquiredExp, Boolean hasRecord, Boolean hasTimer) {
38+
this.habit = habit;
39+
this.streakCount = (streakCount != null) ? streakCount : 0;
40+
this.acquiredExp = (acquiredExp != null) ? acquiredExp : 0;
41+
this.hasRecord = (hasRecord != null) ? hasRecord : false;
42+
this.hasTimer = (hasTimer != null) ? hasTimer : false;
43+
}
44+
45+
public void updateHasRecord() {
46+
this.hasRecord = true;
47+
}
48+
49+
public void updateHasTimer() {
50+
this.hasTimer = true;
51+
}
52+
53+
public void updateAcquiredExp(int acquiredExp) {
54+
this.acquiredExp += acquiredExp;
55+
}
56+
57+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.cmc.mercury.domain.mypage.repository;
2+
3+
import com.cmc.mercury.domain.mypage.entity.HabitHistory;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.data.jpa.repository.Query;
6+
import org.springframework.data.repository.query.Param;
7+
import org.springframework.stereotype.Repository;
8+
9+
import java.time.LocalDate;
10+
import java.time.LocalDateTime;
11+
import java.util.List;
12+
import java.util.Optional;
13+
14+
@Repository
15+
public interface HabitHistoryRepository extends JpaRepository<HabitHistory, Long> {
16+
17+
// 해당 주간의 기록 조회
18+
@Query("SELECT h FROM HabitHistory h WHERE h.habit.id = :habitId AND h.createdAt BETWEEN :startOfWeek AND :endOfWeek")
19+
List<HabitHistory> findThisWeekByHabitId(
20+
@Param("habitId") Long habitId,
21+
@Param("startOfWeek") LocalDateTime startOfWeek, @Param("endOfWeek") LocalDateTime endOfWeek
22+
);
23+
24+
// 날짜별 기록 조회
25+
@Query("SELECT h FROM HabitHistory h WHERE h.habit.user.id = :userId AND h.createdAt BETWEEN :startOfDay AND :endOfDay")
26+
Optional<HabitHistory> findByHabit_User_IdAndCreatedAt(
27+
@Param("userId") Long userId,
28+
@Param("startOfDay") LocalDateTime startOfDay, @Param("endOfDay") LocalDateTime endOfDay
29+
);
30+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.cmc.mercury.domain.mypage.repository;
2+
3+
import com.cmc.mercury.domain.mypage.entity.Habit;
4+
import org.springframework.data.jpa.repository.JpaRepository;
5+
import org.springframework.stereotype.Repository;
6+
7+
import java.util.Optional;
8+
9+
@Repository
10+
public interface HabitRepository extends JpaRepository<Habit, Long> {
11+
12+
Optional<Habit> findByUser_Id(Long userId);
13+
}

0 commit comments

Comments
 (0)