Skip to content

Commit

Permalink
Merge branch 'main' into feat/paths-controller-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Moon-1C authored Jun 4, 2024
2 parents 5214102 + e15936a commit 35ff2fd
Show file tree
Hide file tree
Showing 18 changed files with 569 additions and 50 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.walking.api.converter;

import com.walking.api.service.dto.PredictedData;
import com.walking.api.web.dto.response.detail.FavoriteTrafficDetail;
import com.walking.api.web.dto.response.detail.PointDetail;
import com.walking.api.web.dto.response.detail.TrafficDetail;
import com.walking.data.entity.traffic.TrafficEntity;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public final class TrafficDetailConverter {

Expand All @@ -15,21 +19,59 @@ private TrafficDetailConverter() {}
* @param predictedData 사이클 정보 와 현재 색상 및 잔여시간을 예측한 데이터
* @return 예측 값을 바탕으로 만든 TrafficDetail
*/
public static TrafficDetail execute(PredictedData predictedData) {
public static TrafficDetail execute(
PredictedData predictedData, Optional<FavoriteTrafficDetail> favoriteTrafficDetail) {

TrafficEntity trafficEntity = predictedData.getTraffic();
boolean isFavorite = false;
String viewName = trafficEntity.getName();

if (favoriteTrafficDetail.isPresent()
&& favoriteTrafficDetail.get().getId().equals(trafficEntity.getId())) {
isFavorite = true;
viewName = favoriteTrafficDetail.get().getName();
}

return TrafficDetail.builder()
.id(trafficEntity.getId())
.color(predictedData.getCurrentColor().toString())
.timeLeft(predictedData.getCurrentTimeLeft())
.color(predictedData.getCurrentColorDescription())
.timeLeft(predictedData.getCurrentTimeLeft().orElse(null))
.point(
PointDetail.builder().lng(trafficEntity.getLng()).lat(trafficEntity.getLat()).build())
.redCycle(predictedData.getRedCycle())
.greenCycle(predictedData.getGreenCycle())
.redCycle(predictedData.getRedCycle().orElse(null))
.greenCycle(predictedData.getGreenCycle().orElse(null))
.detail(TrafficDetailInfoConverter.execute(trafficEntity))
.isFavorite(false)
.viewName(trafficEntity.getName())
.isFavorite(isFavorite)
.viewName(viewName)
.build();
}

/**
* PredictedData를 기반으로 TrafficDetail의 List를 생성합니다.
*
* @param predictedData 사이클 정보 와 현재 색상 및 잔여시간을 예측한 데이터 리스트
* @return 예측 값을 바탕으로 만든 TrafficDetail의 List
*/
public static List<TrafficDetail> execute(List<PredictedData> predictedData) {

return predictedData.stream()
.map(
predictedDatum ->
TrafficDetail.builder()
.id(predictedDatum.getTraffic().getId())
.color(predictedDatum.getCurrentColorDescription())
.timeLeft(predictedDatum.getCurrentTimeLeft().orElse(null))
.point(
PointDetail.builder()
.lng(predictedDatum.getTraffic().getLng())
.lat(predictedDatum.getTraffic().getLat())
.build())
.redCycle(predictedDatum.getRedCycle().orElse(null))
.greenCycle(predictedDatum.getGreenCycle().orElse(null))
.detail(TrafficDetailInfoConverter.execute(predictedDatum.getTraffic()))
.isFavorite(false)
.viewName(predictedDatum.getTraffic().getName())
.build())
.collect(Collectors.toList());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.walking.api.domain.traffic.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class AddFavoriteTrafficUseCaseRequest {

private Long memberId;
private Long trafficId;
private String trafficAlias;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.walking.api.domain.traffic.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class BrowseFavoriteTrafficsUseCaseRequest {

private Long memberId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.walking.api.domain.traffic.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class DeleteFavoriteTrafficUseCaseRequest {

private Long favoriteTrafficId;
private Long memberId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.walking.api.domain.traffic.dto;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
public class UpdateFavoriteTrafficUseCaseRequest {

private Long memberId;
private Long favoriteTrafficId;
private String trafficAlias;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.walking.api.domain.traffic.usecase;

import com.walking.api.domain.traffic.dto.AddFavoriteTrafficUseCaseRequest;
import com.walking.api.repository.traffic.TrafficFavoritesRepository;
import com.walking.data.entity.member.MemberEntity;
import com.walking.data.entity.member.TrafficFavoritesEntity;
import com.walking.data.entity.traffic.TrafficEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class AddFavoriteTrafficUseCase {

private final TrafficFavoritesRepository trafficFavoritesRepository;

@Transactional
public boolean execute(AddFavoriteTrafficUseCaseRequest request) {
TrafficFavoritesEntity entity =
TrafficFavoritesEntity.builder()
.memberFk(MemberEntity.builder().id(request.getMemberId()).build())
.trafficFk(TrafficEntity.builder().id(request.getTrafficId()).build())
.alias(request.getTrafficAlias())
.build();

trafficFavoritesRepository.save(entity);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.walking.api.domain.traffic.usecase;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.walking.api.domain.traffic.dto.BrowseFavoriteTrafficsUseCaseRequest;
import com.walking.api.repository.traffic.TrafficFavoritesRepository;
import com.walking.api.web.dto.response.BrowseFavoriteTrafficsResponse;
import com.walking.api.web.dto.response.detail.FavoriteTrafficDetail;
import com.walking.api.web.dto.response.detail.PointDetail;
import com.walking.api.web.dto.response.detail.TrafficDetailInfo;
import com.walking.data.entity.member.MemberEntity;
import com.walking.data.entity.member.TrafficFavoritesEntity;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.locationtech.jts.geom.Point;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class BrowseFavoriteTrafficsUseCase {

private final TrafficFavoritesRepository trafficFavoritesRepository;
private final ObjectMapper objectMapper;

@Transactional
public BrowseFavoriteTrafficsResponse execute(BrowseFavoriteTrafficsUseCaseRequest request) {
List<TrafficFavoritesEntity> trafficFavorites =
trafficFavoritesRepository.findByMemberFk(
MemberEntity.builder().id(request.getMemberId()).build());

List<FavoriteTrafficDetail> details = new ArrayList<>();
for (TrafficFavoritesEntity entity : trafficFavorites) {
TrafficDetailInfo detailInfo =
objectMapper.convertValue(entity.getTrafficFk().getDetail(), TrafficDetailInfo.class);
Point point = entity.getTrafficFk().getPoint();
details.add(
FavoriteTrafficDetail.builder()
.id(entity.getId())
.detail(detailInfo)
.name(entity.getAlias())
.point(PointDetail.builder().lat(point.getY()).lng(point.getX()).build())
.createdAt(entity.getCreatedAt())
.build());
}

return BrowseFavoriteTrafficsResponse.builder().traffics(details).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.walking.api.domain.traffic.usecase;

import com.walking.api.domain.traffic.dto.DeleteFavoriteTrafficUseCaseRequest;
import com.walking.api.repository.traffic.TrafficFavoritesRepository;
import com.walking.data.entity.member.MemberEntity;
import com.walking.data.entity.member.TrafficFavoritesEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class DeleteFavoriteTrafficUseCase {
private final TrafficFavoritesRepository trafficFavoritesRepository;

@Transactional
public boolean execute(DeleteFavoriteTrafficUseCaseRequest request) {
TrafficFavoritesEntity favoriteTraffic =
trafficFavoritesRepository
.findByIdAndMemberFkAndDeletedFalse(
request.getFavoriteTrafficId(),
MemberEntity.builder().id(request.getMemberId()).build())
.orElseThrow(() -> new IllegalArgumentException("해당 즐겨찾기 정보가 존재하지 않습니다."));
trafficFavoritesRepository.delete(favoriteTraffic);
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.walking.api.domain.traffic.usecase;

import com.walking.api.domain.traffic.dto.UpdateFavoriteTrafficUseCaseRequest;
import com.walking.api.repository.traffic.TrafficFavoritesRepository;
import com.walking.data.entity.member.TrafficFavoritesEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
@RequiredArgsConstructor
public class UpdateFavoriteTrafficUseCase {

private final TrafficFavoritesRepository trafficFavoritesRepository;

@Transactional
public boolean execute(UpdateFavoriteTrafficUseCaseRequest request) {
TrafficFavoritesEntity favoriteTraffic =
trafficFavoritesRepository
.findByIdAndDeletedFalse(request.getFavoriteTrafficId())
.orElseThrow(() -> new RuntimeException("TrafficFavoritesEntity not found"));

TrafficFavoritesEntity updatedAlias = favoriteTraffic.updateAlias(request.getTrafficAlias());
trafficFavoritesRepository.save(updatedAlias);
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@
import com.walking.data.entity.member.MemberEntity;
import com.walking.data.entity.member.TrafficFavoritesEntity;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface TrafficFavoritesRepository extends JpaRepository<TrafficFavoritesEntity, Long> {

List<TrafficFavoritesEntity> findByMemberFk(MemberEntity memberFk);

Optional<TrafficFavoritesEntity> findByIdAndDeletedFalse(Long id);

Optional<TrafficFavoritesEntity> findByIdAndMemberFkAndDeletedFalse(
Long id, MemberEntity memberFk);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public interface TrafficRepository extends JpaRepository<TrafficEntity, Long> {
@Query("SELECT t FROM TrafficEntity t where t.id IN :ids")
List<TrafficEntity> findByIds(@Param("ids") List<Long> ids);


// 주변 1km의 Polygon을 만들어 인덱스를 타도록
@Query(
value =
Expand All @@ -33,4 +34,37 @@ public interface TrafficRepository extends JpaRepository<TrafficEntity, Long> {
nativeQuery = true)
List<TrafficEntity> findClosetTrafficByLocation(
@Param("longitude") Double longitude, @Param("latitude") Double latitude);

@Query(
value =
"SELECT * FROM traffic "
+ "WHERE ST_Equals(point_value, "
+ "ST_PointFromText(CONCAT('POINT(', :lat, ' ', :lng, ')'), 4326))",
nativeQuery = true)
List<TrafficEntity> findByLocation(@Param("lat") Double lat, @Param("lng") Double lng);

@Query(
"SELECT t FROM TrafficEntity t "
+ "WHERE FUNCTION('ST_Distance_Sphere', t.point, "
+ "FUNCTION('ST_PointFromText', CONCAT('POINT(', :lat, ' ', :lng, ')'), 4326)) < :distance")
List<TrafficEntity> findByLocationAndDistance(
@Param("lat") Float lat, @Param("lng") Float lng, @Param("distance") Integer distance);

@Query(
value =
"SELECT * FROM traffic "
+ "WHERE ST_Contains("
+ " ST_SRID("
+ " ST_MakeEnvelope("
+ " POINT(:blLng, :blLat), "
+ " POINT(:trLng, :trLat)"
+ " ), 4326"
+ " ), point_value"
+ ")",
nativeQuery = true)
List<TrafficEntity> findTrafficWithinBounds(
@Param("blLng") float blLng,
@Param("blLat") float blLat,
@Param("trLng") float trLng,
@Param("trLat") float trLat);
}
Loading

0 comments on commit 35ff2fd

Please sign in to comment.