-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feature] - 여행기 정렬 및 날짜별 필터링 추가 #442
Changes from all commits
aa0cfa1
0921781
baa3a37
7540226
f4cd65a
2c6a6f1
188a27d
73768c2
c3e79ac
8e23ff7
f812e0e
44428f1
ed96678
9959a83
8936f13
16d469d
531a7b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
import lombok.EqualsAndHashCode; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import org.hibernate.annotations.ColumnDefault; | ||
import org.hibernate.annotations.SQLDelete; | ||
import org.hibernate.annotations.SQLRestriction; | ||
|
||
|
@@ -34,6 +35,7 @@ public class Travelogue extends BaseEntity { | |
|
||
private static final int MIN_TITLE_LENGTH = 1; | ||
private static final int MAX_TITLE_LENGTH = 20; | ||
private static final int LIKE_COUNT_WEIGHT = 1; | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
|
@@ -49,19 +51,23 @@ public class Travelogue extends BaseEntity { | |
@Column(nullable = false) | ||
private String thumbnail; | ||
|
||
@Column(nullable = false) | ||
private Long likeCount; | ||
|
||
@OneToMany(mappedBy = "travelogue", cascade = CascadeType.ALL, orphanRemoval = true) | ||
private List<TravelogueDay> travelogueDays = new ArrayList<>(); | ||
|
||
public Travelogue(Long id, Member author, String title, String thumbnail) { | ||
private Travelogue(Long id, Member author, String title, String thumbnail, Long likeCount) { | ||
validate(author, title, thumbnail); | ||
this.id = id; | ||
this.author = author; | ||
this.title = title; | ||
this.thumbnail = thumbnail; | ||
this.likeCount = likeCount; | ||
} | ||
|
||
public Travelogue(Member author, String title, String thumbnail) { | ||
this(null, author, title, thumbnail); | ||
this(null, author, title, thumbnail, 0L); | ||
} | ||
|
||
public void update(String title, String thumbnail) { | ||
|
@@ -101,6 +107,14 @@ private void validateThumbnailFormat(String thumbnailUrl) { | |
throw new BadRequestException("이미지 url 형식이 잘못되었습니다"); | ||
} | ||
} | ||
|
||
public void increaseLikeCount() { | ||
likeCount += LIKE_COUNT_WEIGHT; | ||
} | ||
|
||
public void decreaseLikeCount() { | ||
likeCount -= LIKE_COUNT_WEIGHT; | ||
} | ||
Comment on lines
+111
to
+117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 개인적으로는 +1이 좀 더 가독성 있다고 생각하는데 어떻게 생각하시나유? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 1이 가독성 있긴한데 매직넘버라 생각해 분리해뒀습니다.하나로 관리하는게 증가, 삭제 일관성 지키기도 더 쉬울 것 같구요. |
||
|
||
public boolean isAuthor(Member author) { | ||
return Objects.equals(author.getId(), this.author.getId()); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package kr.touroot.travelogue.domain; | ||
|
||
import java.util.List; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public class TravelogueFilterCondition { | ||
|
||
public static final int MAX_PERIOD_BOUNDARY = 8; | ||
|
||
private final List<Long> tag; | ||
private final Integer period; | ||
|
||
public boolean isEmptyTagCondition() { | ||
return tag == null; | ||
} | ||
|
||
public boolean isEmptyPeriodCondition() { | ||
return period == null; | ||
} | ||
|
||
public boolean isEmptyCondition() { | ||
return isEmptyTagCondition() && isEmptyPeriodCondition(); | ||
} | ||
|
||
public boolean isMaxPeriod() { | ||
return period == MAX_PERIOD_BOUNDARY; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package kr.touroot.travelogue.dto.request; | ||
|
||
import java.util.List; | ||
import kr.touroot.travelogue.domain.TravelogueFilterCondition; | ||
|
||
public record TravelogueFilterRequest(List<Long> tag, Integer period) { | ||
|
||
public TravelogueFilterCondition toFilterCondition() { | ||
return new TravelogueFilterCondition(tag, period); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,11 @@ | |
import kr.touroot.tag.dto.TagResponse; | ||
import kr.touroot.travelogue.domain.Travelogue; | ||
import kr.touroot.travelogue.domain.TravelogueDay; | ||
import kr.touroot.travelogue.domain.TravelogueFilterCondition; | ||
import kr.touroot.travelogue.domain.TraveloguePhoto; | ||
import kr.touroot.travelogue.domain.TraveloguePlace; | ||
import kr.touroot.travelogue.dto.request.TravelogueDayRequest; | ||
import kr.touroot.travelogue.dto.request.TravelogueFilterRequest; | ||
import kr.touroot.travelogue.dto.request.TraveloguePhotoRequest; | ||
import kr.touroot.travelogue.dto.request.TraveloguePlaceRequest; | ||
import kr.touroot.travelogue.dto.request.TravelogueRequest; | ||
|
@@ -131,15 +133,21 @@ private List<String> findPhotoUrlsOfTraveloguePlace(TraveloguePlace place) { | |
} | ||
|
||
@Transactional(readOnly = true) | ||
public Page<TravelogueSimpleResponse> findSimpleTravelogues(Pageable pageable) { | ||
Page<Travelogue> travelogues = travelogueService.findAll(pageable); | ||
public Page<TravelogueSimpleResponse> findSimpleTravelogues( | ||
TravelogueFilterRequest filterRequest, | ||
Pageable pageable | ||
) { | ||
TravelogueFilterCondition filter = filterRequest.toFilterCondition(); | ||
Page<Travelogue> travelogues = findSimpleTraveloguesByFilter(filter, pageable); | ||
return travelogues.map(this::getTravelogueSimpleResponse); | ||
} | ||
|
||
@Transactional(readOnly = true) | ||
public Page<TravelogueSimpleResponse> findSimpleTravelogues(List<Long> tagFilter, Pageable pageable) { | ||
Page<Travelogue> travelogues = travelogueService.findAllByFilter(tagFilter, pageable); | ||
return travelogues.map(this::getTravelogueSimpleResponse); | ||
private Page<Travelogue> findSimpleTraveloguesByFilter(TravelogueFilterCondition filter, Pageable pageable) { | ||
if (filter.isEmptyCondition()) { | ||
return travelogueService.findAll(pageable); | ||
} | ||
|
||
return travelogueService.findAllByFilter(filter, pageable); | ||
Comment on lines
+145
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 너무 클린 & 깔끔 |
||
} | ||
|
||
@Transactional(readOnly = true) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,14 @@ | ||
package kr.touroot.travelogue.service; | ||
|
||
import java.util.List; | ||
import kr.touroot.global.exception.BadRequestException; | ||
import kr.touroot.global.exception.ForbiddenException; | ||
import kr.touroot.image.infrastructure.AwsS3Provider; | ||
import kr.touroot.member.domain.Member; | ||
import kr.touroot.travelogue.domain.Travelogue; | ||
import kr.touroot.travelogue.domain.TravelogueFilterCondition; | ||
import kr.touroot.travelogue.dto.request.TravelogueRequest; | ||
import kr.touroot.travelogue.domain.search.SearchCondition; | ||
import kr.touroot.travelogue.domain.search.SearchType; | ||
import kr.touroot.travelogue.dto.request.TravelogueRequest; | ||
import kr.touroot.travelogue.dto.request.TravelogueSearchRequest; | ||
import kr.touroot.travelogue.repository.TravelogueRepository; | ||
import kr.touroot.travelogue.repository.query.TravelogueQueryRepository; | ||
|
@@ -58,8 +58,8 @@ public Page<Travelogue> findByKeyword(TravelogueSearchRequest request, Pageable | |
} | ||
|
||
@Transactional(readOnly = true) | ||
public Page<Travelogue> findAllByFilter(List<Long> filter, Pageable pageable) { | ||
return travelogueQueryRepository.findAllByTag(filter, pageable); | ||
public Page<Travelogue> findAllByFilter(TravelogueFilterCondition filter, Pageable pageable) { | ||
return travelogueQueryRepository.findAllByFilter(filter, pageable); | ||
Comment on lines
-61
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍🏻 👍🏻 추상화 좋군요 |
||
} | ||
|
||
@Transactional | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
ALTER TABLE travelogue ADD like_count BIGINT; | ||
|
||
UPDATE travelogue AS t LEFT JOIN (SELECT travelogue_id, COUNT(*) AS like_count | ||
FROM travelogue_like | ||
GROUP BY travelogue_id) AS tl ON t.id = tl.travelogue_id | ||
SET t.like_count = COALESCE(tl.like_count, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
변경 감지를 이용하게 되면서, 서로 다른 트랜잭션에서 race condition 이 발생할 수 있겠네요!
저희 모두 인지는 하고 있으나, 현재 데모데이 요구사항을 지키는 것이 더 우선순위가 높은 것 같아 다음 스프린트 때 해결해 보도록 하시죠!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
인지해두겠습니다 👍