Skip to content

Commit 6ec10e0

Browse files
committed
merge: feature/mypage into develop
2 parents 17c4d63 + f7c45bf commit 6ec10e0

File tree

17 files changed

+609
-9
lines changed

17 files changed

+609
-9
lines changed

src/main/java/com/example/log4u/common/entity/BaseEntity.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,15 @@
99
import jakarta.persistence.Column;
1010
import jakarta.persistence.EntityListeners;
1111
import jakarta.persistence.MappedSuperclass;
12+
import lombok.AccessLevel;
13+
import lombok.AllArgsConstructor;
1214
import lombok.Getter;
15+
import lombok.NoArgsConstructor;
16+
import lombok.experimental.SuperBuilder;
1317

18+
@SuperBuilder
19+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
20+
@AllArgsConstructor(access = AccessLevel.PACKAGE)
1421
@Getter
1522
@MappedSuperclass
1623
@EntityListeners(AuditingEntityListener.class)
@@ -21,6 +28,5 @@ abstract public class BaseEntity {
2128
private LocalDateTime createdAt;
2229

2330
@LastModifiedDate
24-
@Column(nullable = false)
2531
private LocalDateTime updatedAt;
2632
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.example.log4u.common.util;
2+
3+
import java.util.List;
4+
5+
import org.springframework.data.domain.Pageable;
6+
import org.springframework.data.domain.Slice;
7+
import org.springframework.data.domain.SliceImpl;
8+
9+
public class PageableUtil {
10+
public static <T> Slice<T> checkAndCreateSlice(List<T> content, Pageable pageable) {
11+
boolean hasNext = content.size() > pageable.getPageSize();
12+
13+
// 다음 페이지가 있으면 마지막 항목 제거
14+
if (hasNext) {
15+
content.remove(content.size() - 1); // removeLast() 대신 인덱스로 처리
16+
}
17+
18+
return new SliceImpl<>(content, pageable, hasNext);
19+
}
20+
}

src/main/java/com/example/log4u/domain/diary/repository/CustomDiaryRepository.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ Slice<Diary> findByUserIdAndVisibilityInAndCursorId(
2626
Pageable pageable
2727
);
2828

29+
Slice<Diary> getLikeDiarySliceByUserId(
30+
Long userId,
31+
List<VisibilityType> visibilities,
32+
Long cursorId,
33+
Pageable pageable);
34+
2935
List<DiaryMarkerResponseDto> findDiariesInBounds(double south, double north, double west, double east);
3036

3137
List<Diary> findInBoundsByUserId(Long userId, double south, double north, double west, double east);

src/main/java/com/example/log4u/domain/diary/repository/CustomDiaryRepositoryImpl.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import com.example.log4u.domain.diary.VisibilityType;
1515
import com.example.log4u.domain.diary.entity.Diary;
1616
import com.example.log4u.domain.diary.entity.QDiary;
17+
import com.example.log4u.domain.like.entity.QLike;
1718
import com.example.log4u.domain.map.dto.response.DiaryMarkerResponseDto;
1819
import com.querydsl.core.types.OrderSpecifier;
1920
import com.querydsl.core.types.Projections;
@@ -29,14 +30,17 @@ public class CustomDiaryRepositoryImpl implements CustomDiaryRepository {
2930

3031
private final JPAQueryFactory queryFactory;
3132

33+
private final QDiary diary = QDiary.diary;
34+
private final QLike like = QLike.like;
35+
3236
@Override
3337
public Page<Diary> searchDiaries(
3438
String keyword,
3539
List<VisibilityType> visibilities,
3640
SortType sort,
3741
Pageable pageable
3842
) {
39-
QDiary diary = QDiary.diary;
43+
// QDiary diary = QDiary.diary;
4044

4145
// 조건 생성
4246
BooleanExpression condition = createCondition(diary, keyword, visibilities, null);
@@ -138,6 +142,33 @@ private Slice<Diary> checkAndCreateSlice(List<Diary> content, Pageable pageable)
138142
return new SliceImpl<>(content, pageable, hasNext);
139143
}
140144

145+
@Override
146+
public Slice<Diary> getLikeDiarySliceByUserId(
147+
Long userId,
148+
List<VisibilityType> visibilities,
149+
Long cursorId,
150+
Pageable pageable) {
151+
QDiary diary = QDiary.diary;
152+
153+
// 조건 생성
154+
BooleanExpression condition = createCondition(diary, null, visibilities, userId);
155+
156+
// limit + 1로 다음 페이지 존재 여부 확인
157+
List<Diary> content = queryFactory
158+
.selectFrom(diary)
159+
.innerJoin(like)
160+
.on(like.diaryId.eq(diary.diaryId))
161+
.where(like.userId.eq(userId)
162+
.and(condition)
163+
.and(like.likeId.lt(cursorId)))
164+
.orderBy(like.createdAt.desc())
165+
.limit(pageable.getPageSize() + 1)
166+
.fetch();
167+
168+
// 다음 페이지 여부를 계산하여 반환
169+
return checkAndCreateSlice(content, pageable);
170+
}
171+
141172
@Override
142173
public List<DiaryMarkerResponseDto> findDiariesInBounds(double south, double north, double west, double east) {
143174
QDiary d = QDiary.diary;

src/main/java/com/example/log4u/domain/diary/service/DiaryService.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,44 @@ public void checkDiaryExists(Long diaryId) {
218218
throw new NotFoundDiaryException();
219219
}
220220
}
221+
222+
@Transactional(readOnly = true)
223+
public PageResponse<DiaryResponseDto> getMyDiariesByCursor(Long userId, VisibilityType visibilityType,
224+
Long cursorId, int size) {
225+
List<VisibilityType> visibilities =
226+
visibilityType == null ? List.of(VisibilityType.PUBLIC, VisibilityType.PRIVATE, VisibilityType.FOLLOWER) :
227+
List.of(visibilityType);
228+
229+
Slice<Diary> diaries = diaryRepository.findByUserIdAndVisibilityInAndCursorId(
230+
userId,
231+
visibilities,
232+
cursorId != null ? cursorId : Long.MAX_VALUE,
233+
PageRequest.of(0, size)
234+
);
235+
236+
Slice<DiaryResponseDto> dtoSlice = mapToDtoSlice(diaries);
237+
238+
Long nextCursor = !dtoSlice.isEmpty() ? dtoSlice.getContent().getLast().diaryId() : null;
239+
240+
return PageResponse.of(dtoSlice, nextCursor);
241+
}
242+
243+
@Transactional(readOnly = true)
244+
public PageResponse<DiaryResponseDto> getLikeDiariesByCursor(Long userId, Long targetUserId, Long cursorId,
245+
int size) {
246+
List<VisibilityType> visibilities = determineAccessibleVisibilities(userId, targetUserId);
247+
248+
Slice<Diary> diaries = diaryRepository.getLikeDiarySliceByUserId(
249+
targetUserId,
250+
visibilities,
251+
cursorId != null ? cursorId : Long.MAX_VALUE,
252+
PageRequest.of(0, size)
253+
);
254+
255+
Slice<DiaryResponseDto> dtoSlice = mapToDtoSlice(diaries);
256+
257+
Long nextCursor = !dtoSlice.isEmpty() ? dtoSlice.getContent().getLast().diaryId() : null;
258+
259+
return PageResponse.of(dtoSlice, nextCursor);
260+
}
221261
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.example.log4u.domain.follow.repository;
2+
3+
import java.util.List;
4+
5+
import org.springframework.data.domain.Pageable;
6+
import org.springframework.data.domain.Slice;
7+
import org.springframework.data.jpa.repository.support.QuerydslRepositorySupport;
8+
import org.springframework.stereotype.Repository;
9+
10+
import com.example.log4u.common.util.PageableUtil;
11+
import com.example.log4u.domain.follow.entitiy.Follow;
12+
import com.example.log4u.domain.follow.entitiy.QFollow;
13+
import com.example.log4u.domain.user.dto.UserThumbnailResponseDto;
14+
import com.example.log4u.domain.user.entity.QUser;
15+
import com.querydsl.core.BooleanBuilder;
16+
import com.querydsl.core.types.Projections;
17+
import com.querydsl.core.types.dsl.NumberPath;
18+
19+
@Repository
20+
public class FollowQuerydsl extends QuerydslRepositorySupport {
21+
private final QFollow follow = QFollow.follow;
22+
private final QUser user = QUser.user;
23+
24+
public FollowQuerydsl() {
25+
super(Follow.class);
26+
}
27+
28+
private NumberPath<Long> getNumberPath(boolean isFollowerQuery) {
29+
return isFollowerQuery ? follow.followerId : follow.followingId;
30+
}
31+
32+
private BooleanBuilder getBooleanBuilder(boolean isFollowerQuery, Long userId, Long cursorId) {
33+
BooleanBuilder builder = new BooleanBuilder();
34+
builder.and(getNumberPath(isFollowerQuery).eq(userId));
35+
36+
if (cursorId != null) {
37+
builder.and(follow.id.lt(cursorId));
38+
}
39+
40+
return builder;
41+
}
42+
43+
private List<UserThumbnailResponseDto> getContent(boolean isFollowerQuery, Long userId, Long cursorId) {
44+
BooleanBuilder builder = getBooleanBuilder(isFollowerQuery, userId, cursorId);
45+
46+
return from(follow)
47+
.select(Projections.constructor(UserThumbnailResponseDto.class,
48+
getNumberPath(!isFollowerQuery),
49+
user.nickname,
50+
user.nickname))
51+
.where(builder)
52+
.distinct()
53+
.fetch();
54+
}
55+
56+
//내 팔로워 아이디 슬라이스
57+
public Slice<UserThumbnailResponseDto> getFollowerSliceByUserId(Long userId, Long cursorId, Pageable pageable) {
58+
boolean isFollowerQuery = true;
59+
List<UserThumbnailResponseDto> content = getContent(isFollowerQuery, userId, cursorId);
60+
return PageableUtil.checkAndCreateSlice(content, pageable);
61+
}
62+
63+
// 내가 팔로잉하는 아이디 슬라이스
64+
public Slice<UserThumbnailResponseDto> getFollowingSliceByUserId(Long userId, Long cursorId, Pageable pageable) {
65+
boolean isFollowerQuery = false;
66+
List<UserThumbnailResponseDto> content = getContent(isFollowerQuery, userId, cursorId);
67+
return PageableUtil.checkAndCreateSlice(content, pageable);
68+
}
69+
}

src/main/java/com/example/log4u/domain/reports/controller/ReportsController.java

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

33
import org.springframework.http.HttpStatus;
44
import org.springframework.http.ResponseEntity;
5+
import org.springframework.security.core.annotation.AuthenticationPrincipal;
56
import org.springframework.web.bind.annotation.PathVariable;
67
import org.springframework.web.bind.annotation.PostMapping;
78
import org.springframework.web.bind.annotation.RequestBody;
89
import org.springframework.web.bind.annotation.RequestMapping;
910
import org.springframework.web.bind.annotation.RestController;
1011

12+
import com.example.log4u.common.oauth2.dto.CustomOAuth2User;
1113
import com.example.log4u.domain.reports.dto.ReportCreateRequestDto;
1214
import com.example.log4u.domain.reports.service.ReportService;
1315

@@ -21,18 +23,22 @@ public class ReportsController {
2123

2224
@PostMapping("/diaries/{diaryId}")
2325
public ResponseEntity<Void> createReportForDiary(
26+
@AuthenticationPrincipal CustomOAuth2User customOAuth2User,
2427
@RequestBody ReportCreateRequestDto reportCreateRequestDto,
25-
@PathVariable Long diaryId) {
26-
long reporterId = 1L; // SecurityContextHolder 에서 온다고 가정
28+
@PathVariable Long diaryId
29+
) {
30+
long reporterId = customOAuth2User.getUserId();
2731
reportService.createDiaryReport(reporterId, reportCreateRequestDto, diaryId);
2832
return new ResponseEntity<>(HttpStatus.CREATED);
2933
}
3034

3135
@PostMapping("/comments/{commentId}")
3236
public ResponseEntity<Void> createReport(
37+
@AuthenticationPrincipal CustomOAuth2User customOAuth2User,
3338
@RequestBody ReportCreateRequestDto reportCreateRequestDto,
34-
@PathVariable Long commentId) {
35-
long reporterId = 1L;
39+
@PathVariable Long commentId
40+
) {
41+
long reporterId = customOAuth2User.getUserId();
3642
reportService.createCommentReport(reporterId, reportCreateRequestDto, commentId);
3743
return new ResponseEntity<>(HttpStatus.CREATED);
3844
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example.log4u.domain.subscription;
2+
3+
public enum PaymentProvider {
4+
TOSS,
5+
KAKAO,
6+
NAVER
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.example.log4u.domain.subscription;
2+
3+
public enum PaymentStatus {
4+
SUCCESS, // 결제 완료
5+
FAILED, // 결제 실패
6+
REFUNDED // 환불 완료
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.example.log4u.domain.subscription.dto;
2+
3+
import java.time.LocalDateTime;
4+
5+
import com.example.log4u.domain.subscription.PaymentProvider;
6+
7+
import jakarta.annotation.Nullable;
8+
import lombok.Builder;
9+
10+
@Builder
11+
public record SubscriptionResponseDto(
12+
boolean isSubscriptionActive,
13+
14+
@Nullable
15+
PaymentProvider paymentProvider,
16+
17+
@Nullable
18+
LocalDateTime startDate
19+
) {
20+
}

0 commit comments

Comments
 (0)