Skip to content

Commit

Permalink
Merge pull request #87 from LikeKNU/develop
Browse files Browse the repository at this point in the history
시내버스 경로 관련 기능
  • Loading branch information
jcw1031 authored Dec 10, 2023
2 parents 38b3913 + a03280f commit 8881e52
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ResponseDto<List<MainCityBusResponse>> getMainPageCityBuses(
throw new BusinessException("Invalid campus");
}

List<MainCityBusResponse> cityBuses = cityBusService.earliestOutgoingCityBuses(campus);
List<MainCityBusResponse> cityBuses = cityBusService.earliestArriveCityBuses(campus);
return ResponseDto.of(cityBuses);
}

Expand Down
3 changes: 3 additions & 0 deletions src/main/java/ac/knu/likeknu/domain/Route.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ public class Route {
@Enumerated(value = EnumType.STRING)
private Campus campus;

@Column(nullable = false)
private int sequence;

@JoinTable(name = "bus_route",
joinColumns = @JoinColumn(name = "route_id"),
inverseJoinColumns = @JoinColumn(name = "bus_id"))
Expand Down
52 changes: 36 additions & 16 deletions src/main/java/ac/knu/likeknu/service/CityBusService.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
@Service
public class CityBusService {

private static final int MAX_BUSES_SIZE = 5;
private static final int MAX_MAIN_ROUTES_SIZE = 3;
private static final int MAX_ARRIVAL_TIMES_SIZE = 5;
private static final LocalTime ROUTE_TYPE_CHANGE_TIME = LocalTime.of(12, 0);

private final RouteRepository routeRepository;
private final CityBusRepository cityBusRepository;
Expand All @@ -36,22 +38,36 @@ public CityBusService(RouteRepository routeRepository, CityBusRepository cityBus
}

/**
* 학교에서 외부로 가는 가장 금방 도착하는 시내버스 정보
* 학교에서 출발하거나 돌아오는 경로 중 가장 금방 도착하는 시내버스 정보
*
* @param campus 캠퍼스
* @return 캠퍼스별 학교에서 나가는 가장 빠른 시내버스 목록
* @return 캠퍼스별 학교에서 출발하거나 돌아오는 경로의 가장 빠른 시내버스 목록
*/
public List<MainCityBusResponse> earliestOutgoingCityBuses(Campus campus) {
public List<MainCityBusResponse> earliestArriveCityBuses(Campus campus) {
RouteType routeType = getRouteType(LocalTime.now());
return routeRepository.findByCampus(campus, Sort.by(Order.asc("origin"))).stream()
.filter(route -> route.getRouteType().equals(RouteType.OUTGOING))
.map(route -> {
CityBus earliestBus = getEarliestCityBus(cityBusRepository.findByRoutesContaining(route));
return earliestBus == null ? MainCityBusResponse.empty(route)
: MainCityBusResponse.of(route, earliestBus);
})
.filter(route -> route.getRouteType().equals(routeType))
.sorted(Comparator.comparing(Route::getSequence))
.map(this::generateMainCityBusResponse)
.limit(MAX_MAIN_ROUTES_SIZE)
.toList();
}

private RouteType getRouteType(LocalTime time) {
if (time.isBefore(ROUTE_TYPE_CHANGE_TIME)) {
return RouteType.INCOMING;
}
return RouteType.OUTGOING;
}

private MainCityBusResponse generateMainCityBusResponse(Route route) {
CityBus earliestBus = getEarliestCityBus(cityBusRepository.findByRoutesContaining(route));
if (earliestBus == null) {
return MainCityBusResponse.empty(route);
}
return MainCityBusResponse.of(route, earliestBus);
}

private CityBus getEarliestCityBus(List<CityBus> buses) {
return buses.stream()
.filter(cityBus -> cityBus.getEarliestArrivalTime() != null)
Expand All @@ -62,27 +78,31 @@ private CityBus getEarliestCityBus(List<CityBus> buses) {
/**
* 특정 경로의 시내버스 도착 시간 조회
*
* @param routeId 경로 ID
* @param campus 캠퍼스
* @param routeType 경로 종류(들어오는 거, 나가는 거)
* @return 특정 경로의 시내버스 도착 시간 목록
*/
public List<CityBusesResponse> getCityBusesArrivalTime(Campus campus, RouteType routeType) {
List<Route> routes = routeRepository.findByCampusAndRouteType(campus, routeType);
return routes.stream()
.map(route -> {
List<CityBusesArrivalTimeResponse> cityBusesArrivalTime = getCityBusesArrivalTime(route);
return CityBusesResponse.of(route, cityBusesArrivalTime);
})
.sorted(Comparator.comparing(Route::getSequence))
.map(this::generateCityBusesResponse)
.toList();
}

private CityBusesResponse generateCityBusesResponse(Route route) {
List<CityBusesArrivalTimeResponse> cityBusesArrivalTime = getCityBusesArrivalTime(route);
return CityBusesResponse.of(route, cityBusesArrivalTime);
}

private List<CityBusesArrivalTimeResponse> getCityBusesArrivalTime(Route route) {
LocalTime currentTime = LocalTime.now();
return cityBusRepository.findByRoutesContaining(route)
.stream()
.flatMap(cityBus -> getCloseArrivalTimesStream(cityBus, currentTime)
.map(arrivalTime -> CityBusesArrivalTimeResponse.of(cityBus, arrivalTime, currentTime)))
.sorted(Comparator.comparing(CityBusesArrivalTimeResponse::arrivalAt))
.limit(MAX_BUSES_SIZE)
.limit(MAX_ARRIVAL_TIMES_SIZE)
.toList();
}

Expand Down
6 changes: 1 addition & 5 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
spring.datasource.url=jdbc:mysql://${DB_HOST}:${DB_PORT}/${DB_SCHEMA}?characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=${DB_USERNAME}
spring.datasource.password=${DB_PASSWORD}

spring.jpa.hibernate.ddl-auto=validate
spring.profiles.active=dev
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ void getCityBusArrivalTimesSuccess() throws Exception {
);

// when
when(cityBusService.earliestOutgoingCityBuses(eq(Campus.CHEONAN)))
when(cityBusService.earliestArriveCityBuses(eq(Campus.CHEONAN)))
.thenReturn(cheonanCityBuses);
when(cityBusService.earliestOutgoingCityBuses(eq(Campus.SINGWAN)))
when(cityBusService.earliestArriveCityBuses(eq(Campus.SINGWAN)))
.thenReturn(singwanCityBuses);

ResultActions cheonanResultActions = mockMvc.perform(get("/api/main/buses")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void earliestOutgoingCityBusesSuccess() throws Exception {
.thenReturn(List.of(cityBus1, cityBus4, cityBus5));

// when
List<MainCityBusResponse> earliestCityBuses = cityBusService.earliestOutgoingCityBuses(Campus.CHEONAN);
List<MainCityBusResponse> earliestCityBuses = cityBusService.earliestArriveCityBuses(Campus.CHEONAN);

// then
MainCityBusResponse mainCityBusResponse = earliestCityBuses.get(1);
Expand Down

0 comments on commit 8881e52

Please sign in to comment.