Skip to content
This repository was archived by the owner on Oct 20, 2024. It is now read-only.

Commit 3b05fff

Browse files
feat: ✨ 감정 별 일기 조회 (#55)
* Initial commit * Feat/#1 oauth2login (#3) * feat: User 엔터티 생성 * feat: jwt 버전 11->12, JWTUtil 생성 * feat: JWTFilter(JwtAuthenticationFilter) 등록 * feat: kakao 로그인 구현 * docs: swagger 태그(Authorization) 추가 (#5) * feat: User 엔터티 생성 * feat: jwt 버전 11->12, JWTUtil 생성 * feat: JWTFilter(JwtAuthenticationFilter) 등록 * feat: kakao 로그인 구현 * docs: swagger 태그(Authorization) 추가 * feat: accesstoken 테스트를 위한 test login 생성 (#9) * feat: User 엔티티에 상속 (#12) * feat: BaseEntity 생성 * feat: User 엔티티에 상속 * feat: 일기 생성 기능 구현 (#14) * feat: accesstoken 테스트를 위한 test login 생성 * feat: 일기 생성 기능 구현 * hotfix: ci 에러 수정 (#16) * feat: accesstoken 테스트를 위한 test login 생성 * feat: 일기 생성 기능 구현 * hotfix: ci 에러 수정 * fix: OIDC 카카오 로그인 nullPointerException 해결 * feat: 닉네임 설정 기능 구현 (#21) * feat: 일기 수정 기능 구현 (#25) * feat: 일기에 감정 컬럼 추가 * feat: 일기 수정 기능 구현 * feat: 일기 삭제 기능 구현 (#27) * feat: 일기에 감정 컬럼 추가 * feat: 일기 수정 기능 구현 * feat: 일기 삭제 기능 구현 * feat: 일기 감정 분석 기능 구현 (#31) * feat: 감정 저장 기능 구현 (#33) * feat: 일기 감정 분석 기능 구현 * feat: 감정 저장 기능 구현 * fix: 🐛 감정 저장 안되던 오류 수정 (#35) * feat: 일기 감정 분석 기능 구현 * feat: 감정 저장 기능 구현 * fix: 🐛 감정 저장 안되던 오류 수정 * hotfix: 🚑 서버 꺼짐 현상 해결 (#37) * feat: 일기 감정 분석 기능 구현 * feat: 감정 저장 기능 구현 * fix: 🐛 감정 저장 안되던 오류 수정 * hotfix: 🚑 서버 꺼짐 현상 해결 * feat: ✨ 홈 화면 조회 기능 구현 (#41) * feat: ✨ 회원가입 완료 여부 필드 추가 (#44) * feat: ✨ 일기 상세 조회 구현 (#47) * feat: ✨ 기간 별 감정 통계 조회 기능 구현 (#50) * feat: ✨ 일기 내용 검색 기능 구현 (#52) * feat: ✨ 감정 별 일기 조회 (#54)
1 parent 420a4c2 commit 3b05fff

File tree

6 files changed

+90
-4
lines changed

6 files changed

+90
-4
lines changed

src/main/java/com/aidiary/domain/diary/domain/repository/DiaryQueryDslRepository.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import com.aidiary.domain.diary.dto.SearchDiariesRes;
44
import com.aidiary.domain.diary.dto.condition.DiariesSearchCondition;
5+
import com.aidiary.domain.emotion.dto.DiarysByEmotionRes;
56
import com.aidiary.domain.emotion.dto.EmotionStatRes;
67
import com.aidiary.domain.home.dto.HomeViewRes;
78
import com.aidiary.domain.user.domain.User;
89
import com.aidiary.global.config.security.token.UserPrincipal;
910
import org.springframework.data.domain.Page;
1011
import org.springframework.data.domain.Pageable;
12+
import org.springframework.data.domain.Slice;
1113

1214
import java.time.LocalDate;
1315
import java.util.List;
@@ -21,4 +23,6 @@ public interface DiaryQueryDslRepository {
2123
EmotionStatRes findEmotionsCountBetweenStartDateAndEndDate(Long id, LocalDate startDate, LocalDate endDate);
2224

2325
Page<SearchDiariesRes> findDiaries(User user, DiariesSearchCondition diariesSearchCondition, Pageable pageable);
26+
27+
Slice<DiarysByEmotionRes> findAllByEmotionAndUserId(String emotion, Long id, Pageable pageable);
2428
}

src/main/java/com/aidiary/domain/diary/domain/repository/DiaryQueryDslRepositoryImpl.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
11
package com.aidiary.domain.diary.domain.repository;
22

3-
import com.aidiary.domain.diary.domain.QDiary;
43
import com.aidiary.domain.diary.dto.QSearchDiariesRes;
54
import com.aidiary.domain.diary.dto.SearchDiariesRes;
65
import com.aidiary.domain.diary.dto.condition.DiariesSearchCondition;
6+
import com.aidiary.domain.emotion.dto.DiarysByEmotionRes;
77
import com.aidiary.domain.emotion.dto.EmotionStatRes;
8+
import com.aidiary.domain.emotion.dto.QDiarysByEmotionRes;
89
import com.aidiary.domain.emotion.dto.QEmotionStatRes;
910
import com.aidiary.domain.home.dto.HomeViewRes;
1011
import com.aidiary.domain.home.dto.QHomeViewRes;
1112
import com.aidiary.domain.user.domain.User;
12-
import com.aidiary.global.config.security.token.UserPrincipal;
13-
import com.querydsl.core.types.Ops;
1413
import com.querydsl.core.types.dsl.*;
1514
import com.querydsl.jpa.impl.JPAQuery;
1615
import com.querydsl.jpa.impl.JPAQueryFactory;
1716
import lombok.RequiredArgsConstructor;
1817
import org.springframework.data.domain.Page;
1918
import org.springframework.data.domain.Pageable;
19+
import org.springframework.data.domain.Slice;
20+
import org.springframework.data.domain.SliceImpl;
2021
import org.springframework.data.support.PageableExecutionUtils;
2122
import org.springframework.stereotype.Repository;
2223

@@ -144,6 +145,37 @@ public Page<SearchDiariesRes> findDiaries(User user, DiariesSearchCondition diar
144145
return PageableExecutionUtils.getPage(results, pageable, countQuery::fetchOne);
145146
}
146147

148+
@Override
149+
public Slice<DiarysByEmotionRes> findAllByEmotionAndUserId(String emotion, Long userId, Pageable pageable) {
150+
List<DiarysByEmotionRes> results = queryFactory
151+
.select(new QDiarysByEmotionRes(
152+
diary.content,
153+
diary.diaryEntryDate
154+
))
155+
.from(diary)
156+
.where(diary.emotion.eq(emotion),
157+
diary.user.id.eq(userId)
158+
)
159+
.orderBy(diary.diaryEntryDate.desc())
160+
.offset(pageable.getOffset())
161+
.limit(pageable.getPageSize())
162+
.fetch();
163+
164+
165+
return toSlice(results, pageable);
166+
}
167+
168+
private Slice<DiarysByEmotionRes> toSlice(List<DiarysByEmotionRes> results, Pageable pageable) {
169+
int pageSize = pageable.getPageSize();
170+
boolean hasNext = false;
171+
172+
if (results.size() > pageSize) {
173+
hasNext = true;
174+
results.remove(pageSize);
175+
}
176+
return new SliceImpl<>(results, pageable, hasNext);
177+
}
178+
147179
public BooleanExpression equalsUser(User user) {
148180
return user != null ? diary.user.eq(user) : null;
149181
}
@@ -155,5 +187,4 @@ private StringTemplate getExcerpt(StringPath content, String keyword) {
155187
);
156188
}
157189

158-
159190
}

src/main/java/com/aidiary/domain/diary/domain/repository/DiaryRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
import com.aidiary.domain.diary.domain.Diary;
44
import org.springframework.data.jpa.repository.JpaRepository;
55

6+
import java.util.List;
7+
import java.util.Optional;
8+
69
public interface DiaryRepository extends JpaRepository<Diary, Long>, DiaryQueryDslRepository {
710
}

src/main/java/com/aidiary/domain/emotion/application/EmotionService.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,21 @@
22

33
import com.aidiary.domain.diary.domain.Diary;
44
import com.aidiary.domain.diary.domain.repository.DiaryRepository;
5+
import com.aidiary.domain.emotion.dto.DiarysByEmotionRes;
56
import com.aidiary.domain.emotion.dto.EmotionStatRes;
67
import com.aidiary.domain.user.domain.User;
78
import com.aidiary.domain.user.domain.repository.UserRepository;
89
import com.aidiary.global.config.security.token.UserPrincipal;
910
import com.aidiary.global.payload.Message;
1011
import jakarta.persistence.EntityNotFoundException;
1112
import lombok.RequiredArgsConstructor;
13+
import org.springframework.data.domain.Pageable;
14+
import org.springframework.data.domain.Slice;
1215
import org.springframework.stereotype.Service;
1316
import org.springframework.transaction.annotation.Transactional;
1417

1518
import java.time.LocalDate;
19+
import java.util.List;
1620

1721
@Service
1822
@RequiredArgsConstructor
@@ -60,10 +64,17 @@ public Message saveEmotion(UserPrincipal userPrincipal, Long diaryId, String emo
6064
.build();
6165
}
6266

67+
@Transactional
6368
public EmotionStatRes loadEmotionStat(UserPrincipal userPrincipal, LocalDate startDate, LocalDate endDate) {
6469

6570
EmotionStatRes emotionsCountBetweenStartDateAndEndDate = diaryRepository.findEmotionsCountBetweenStartDateAndEndDate(userPrincipal.getId(), startDate, endDate);
6671

6772
return emotionsCountBetweenStartDateAndEndDate;
6873
}
74+
75+
@Transactional
76+
public Slice<DiarysByEmotionRes> findDiarys(UserPrincipal userPrincipal, String emotion, Pageable pageable) {
77+
Slice<DiarysByEmotionRes> allByEmotionAndUserId = diaryRepository.findAllByEmotionAndUserId(emotion, userPrincipal.getId(), pageable);
78+
return allByEmotionAndUserId;
79+
}
6980
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.aidiary.domain.emotion.dto;
2+
3+
import com.querydsl.core.annotations.QueryProjection;
4+
import lombok.Builder;
5+
6+
import java.time.LocalDate;
7+
8+
@Builder
9+
public record DiarysByEmotionRes(
10+
String content,
11+
LocalDate diaryEntryDate
12+
) {
13+
14+
@QueryProjection
15+
public DiarysByEmotionRes(String content, LocalDate diaryEntryDate) {
16+
this.content = content;
17+
this.diaryEntryDate = diaryEntryDate;
18+
}
19+
}

src/main/java/com/aidiary/domain/emotion/presentation/EmotionController.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.aidiary.domain.emotion.application.EmotionService;
55
import com.aidiary.domain.emotion.dto.ChatGPTReq;
66
import com.aidiary.domain.emotion.dto.ChatGPTRes;
7+
import com.aidiary.domain.emotion.dto.DiarysByEmotionRes;
78
import com.aidiary.domain.emotion.dto.EmotionStatRes;
89
import com.aidiary.global.config.security.token.CurrentUser;
910
import com.aidiary.global.config.security.token.UserPrincipal;
@@ -20,6 +21,9 @@
2021
import lombok.RequiredArgsConstructor;
2122
import org.springframework.beans.factory.annotation.Value;
2223
import org.springframework.cglib.core.Local;
24+
import org.springframework.data.domain.Pageable;
25+
import org.springframework.data.domain.Slice;
26+
import org.springframework.data.web.PageableDefault;
2327
import org.springframework.web.bind.annotation.*;
2428
import org.springframework.web.client.RestTemplate;
2529

@@ -87,4 +91,18 @@ public ResponseCustom<EmotionStatRes> getEmotionStat(
8791
) {
8892
return ResponseCustom.OK(emotionService.loadEmotionStat(userPrincipal, startDate, endDate));
8993
}
94+
95+
@Operation(summary = "감정 별 일기 조회", description = "감정 별 일기들을 조회합니다.")
96+
@ApiResponses(value = {
97+
@ApiResponse(responseCode = "200", description = "감정 별 일기 조회 성공", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = DiarysByEmotionRes.class))}),
98+
@ApiResponse(responseCode = "400", description = "감정 별 일기 조회 실패", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))}),
99+
})
100+
@GetMapping("/search")
101+
public ResponseCustom<Slice<DiarysByEmotionRes>> findDiarysByEmotion(
102+
@Parameter(description = "Accesstoken을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal,
103+
@Parameter(description = "감정(행복, 우울, 화남, 불안)을 입력해주세요.", required = true) @RequestParam String emotion,
104+
@Parameter(description = "조회할 페이지 크기를 입력해주세요.") @PageableDefault(size = 4) Pageable pageable
105+
) {
106+
return ResponseCustom.OK(emotionService.findDiarys(userPrincipal, emotion, pageable));
107+
}
90108
}

0 commit comments

Comments
 (0)