-
Notifications
You must be signed in to change notification settings - Fork 15
/
CommunityService.java
141 lines (125 loc) · 6.14 KB
/
CommunityService.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package hanglog.community.service;
import static hanglog.community.domain.recommendstrategy.RecommendType.LIKE;
import static hanglog.global.exception.ExceptionCode.NOT_FOUND_TRIP_ID;
import static hanglog.trip.domain.type.PublishedStatusType.PUBLISHED;
import hanglog.auth.domain.Accessor;
import hanglog.city.domain.City;
import hanglog.community.domain.recommendstrategy.RecommendStrategies;
import hanglog.community.domain.recommendstrategy.RecommendStrategy;
import hanglog.community.domain.repository.LikeRepository;
import hanglog.community.dto.CityElement;
import hanglog.community.dto.CityElements;
import hanglog.community.domain.LikeInfo;
import hanglog.community.dto.LikeElement;
import hanglog.community.dto.LikeElements;
import hanglog.community.dto.response.CommunityTripListResponse;
import hanglog.community.dto.response.CommunityTripResponse;
import hanglog.community.dto.response.RecommendTripListResponse;
import hanglog.global.exception.BadRequestException;
import hanglog.trip.domain.Trip;
import hanglog.trip.domain.TripCity;
import hanglog.trip.domain.repository.PublishedTripRepository;
import hanglog.trip.domain.repository.TripCityRepository;
import hanglog.trip.domain.repository.TripRepository;
import hanglog.trip.dto.response.TripDetailResponse;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class CommunityService {
private static final int RECOMMEND_AMOUNT = 5;
private final LikeRepository likeRepository;
private final TripRepository tripRepository;
private final TripCityRepository tripCityRepository;
private final RecommendStrategies recommendStrategies;
private final PublishedTripRepository publishedTripRepository;
public CommunityTripListResponse getCommunityTripsByPage(final Accessor accessor, final Pageable pageable) {
final List<Trip> trips = tripRepository.findPublishedTripByPageable(pageable.previousOrFirst());
final List<CommunityTripResponse> communityTripResponses = getCommunityTripResponses(accessor, trips);
final Long lastPageIndex = getLastPageIndex(pageable.getPageSize());
return new CommunityTripListResponse(communityTripResponses, lastPageIndex);
}
public RecommendTripListResponse getRecommendTrips(final Accessor accessor) {
final RecommendStrategy recommendStrategy = recommendStrategies.mapByRecommendType(LIKE);
final Pageable pageable = Pageable.ofSize(RECOMMEND_AMOUNT);
final List<Trip> trips = recommendStrategy.recommend(pageable);
final List<CommunityTripResponse> communityTripResponses = getCommunityTripResponses(accessor, trips);
return new RecommendTripListResponse(recommendStrategy.getTitle(), communityTripResponses);
}
private List<CommunityTripResponse> getCommunityTripResponses(final Accessor accessor, final List<Trip> trips) {
final List<Long> tripIds = trips.stream().map(Trip::getId).toList();
final List<CityElement> cityElements = tripCityRepository.findTripIdAndCitiesByTripIds(tripIds);
final Map<Long, List<City>> citiesByTrip = CityElements.toCityMap(cityElements);
final List<LikeElement> likeElements = likeRepository.findLikeCountAndIsLikeByTripIds(accessor.getMemberId(), tripIds);
final Map<Long, LikeInfo> likeInfoByTrip = LikeElements.toLikeMap(likeElements);
return trips.stream()
.map(trip -> CommunityTripResponse.of(
trip,
citiesByTrip.get(trip.getId()),
isLike(likeInfoByTrip, trip.getId()),
getLikeCount(likeInfoByTrip, trip.getId())
)).toList();
}
private boolean isLike(final Map<Long, LikeInfo> likeInfoByTrip, final Long tripId) {
final LikeInfo likeInfo = likeInfoByTrip.get(tripId);
if (likeInfo == null) {
return false;
}
return likeInfo.isLike();
}
private Long getLikeCount(final Map<Long, LikeInfo> likeInfoByTrip, final Long tripId) {
final LikeInfo likeInfo = likeInfoByTrip.get(tripId);
if (likeInfo == null) {
return 0L;
}
return likeInfo.getLikeCount();
}
private Long getLastPageIndex(final int pageSize) {
final Long totalTripCount = tripRepository.countTripByPublishedStatus(PUBLISHED);
final long lastPageIndex = totalTripCount / pageSize;
if (totalTripCount % pageSize == 0) {
return lastPageIndex;
}
return lastPageIndex + 1;
}
public TripDetailResponse getTripDetail(final Accessor accessor, final Long tripId) {
final Trip trip = tripRepository.findById(tripId)
.orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ID));
final List<City> cities = getCitiesByTripId(tripId);
final LocalDateTime publishedDate = publishedTripRepository.findByTripId(tripId)
.orElseThrow(() -> new BadRequestException(NOT_FOUND_TRIP_ID))
.getCreatedAt();
final Long likeCount = likeRepository.countLikesByTripId(tripId);
if (!accessor.isMember()) {
return TripDetailResponse.publishedTrip(
trip,
cities,
false,
false,
likeCount,
publishedDate
);
}
final Boolean isWriter = trip.isWriter(accessor.getMemberId());
final Boolean isLike = likeRepository.existsByMemberIdAndTripId(accessor.getMemberId(), tripId);
return TripDetailResponse.publishedTrip(
trip,
cities,
isWriter,
isLike,
likeCount,
publishedDate
);
}
private List<City> getCitiesByTripId(final Long tripId) {
return tripCityRepository.findByTripId(tripId).stream()
.map(TripCity::getCity)
.toList();
}
}