Skip to content

Commit a77c0aa

Browse files
committed
feat: 명소 혼잡도 정보 요일/시간별로 조회할 수 있도록 구현
- 응답값 변경 - 기준 요일, 요일별 혼잡도, 시간대별 혼잡도 추가 - 혼잡도 endpoint 변경 - redis에 저장할 key 변경 - 요일,시간으로 표시하도록 - 요일, 시간으로 혼잡도 구하는 메서드 추가 - redis key 구하는 메서드 extract
1 parent f5b5152 commit a77c0aa

4 files changed

Lines changed: 75 additions & 45 deletions

File tree

src/main/kotlin/busanVibe/busan/domain/place/controller/PlaceCongestionController.kt

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,23 @@ class PlaceCongestionController (
5050
return ApiResponse.onSuccess(place)
5151
}
5252

53-
@GetMapping("/place/{placeId}/real-time")
54-
@Operation(summary = "명소 실시간 혼잡도 조회")
53+
@GetMapping("/place/{placeId}/congestions")
54+
@Operation(summary = "명소 혼잡도 조회",
55+
description =
56+
"""
57+
* congestions_by_day : 각 요일별 현재시간 기준 혼잡도
58+
- index [ 0:월, 1:화 ... 5:토, 6:일 ]
59+
60+
* congestions_by_time : 각 요일별 시간별 혼잡도 ( 0~23시 제공 )
61+
- 명소의 모든 요일의 혼잡도 제공
62+
- 총 7개의 배열, 각 배열에는 24개의 혼잡도 정보 담김
63+
64+
* standard_day와 standard_time 활용해서 현재시간 판단 가능합니다.
65+
이거도 마찬가지로 0:월 ~ 6:일
66+
67+
* 현재(실시간) 혼잡도는 real_time_congestion_level 이용하면 됩니다.
68+
"""
69+
)
5570
fun placeRealTimeCongestion(
5671
@PathVariable("placeId") placeId: Long): ApiResponse<PlaceMapResponseDTO.PlaceCongestionDto>{
5772
val congestion = placeCongestionQueryService.getCongestion(placeId)

src/main/kotlin/busanVibe/busan/domain/place/dto/PlaceMapResponseDTO.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ class PlaceMapResponseDTO {
3939

4040
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
4141
data class PlaceCongestionDto(
42+
val standardDay: Int,
4243
val standardTime: Int,
4344
val realTimeCongestionLevel: Int,
44-
val byTimePercent: List<Float>
45+
val congestionsByDay: List<Float>,
46+
val congestionsByTime: List<List<Float>>
4547
)
4648

4749
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)

src/main/kotlin/busanVibe/busan/domain/place/service/PlaceCongestionQueryService.kt

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -119,28 +119,36 @@ class PlaceCongestionQueryService(
119119
@Transactional(readOnly = true)
120120
fun getCongestion(placeId: Long): PlaceMapResponseDTO.PlaceCongestionDto {
121121

122-
val current = LocalDateTime.now()
123-
log.info("현재 시간: ${current}")
124-
125-
val roundedBase = (current.hour / 3) * 3
126-
127-
// 최근 6개 3시간 단위 시간 생성 (기준시간 포함 총 7개)
128-
val hours = (-3 .. 3).map { i -> (roundedBase - i * 3 + 24) % 24 }
122+
// 현재시간 기준 LocalDateTime
123+
val currentDateTime = LocalDateTime.now()
124+
125+
// 혼잡도 리스트
126+
val congestionsByDay: MutableList<Float> = mutableListOf() // 요일별
127+
val congestionsByTime: MutableList<List<Float>> = mutableListOf() // 시간대별
128+
129+
// 시간대별 혼잡도 ( 월~일, 0~23시 )
130+
for( day in 1..7){
131+
val congestions = mutableListOf<Float>() // 각 요일의 혼잡도 정보 담을 List
132+
for( hour in 0..23){
133+
congestions.add(placeRedisUtil.getTimeCongestion(placeId, day, hour))
134+
}
135+
congestionsByTime.add(congestions)
136+
}
129137

130-
val byTimePercent: List<Float> = hours.map { hour ->
131-
val adjustedDateTime = current.withHour(hour)
132-
.withMinute(0).withSecond(0).withNano(0)
133-
.let {
134-
if (hour > current.hour) it.minusDays(1) else it
135-
}
136-
placeRedisUtil.getTimeCongestion(placeId, adjustedDateTime)
138+
// 요일별 현재 시간의 혼잡도
139+
for( day in 1..7){
140+
congestionsByDay.add(placeRedisUtil.getTimeCongestion(placeId, day, currentDateTime.hour))
137141
}
138142

143+
// DTO 생성 및 반환
139144
return PlaceMapResponseDTO.PlaceCongestionDto(
140-
standardTime = roundedBase,
141-
realTimeCongestionLevel = placeRedisUtil.getTimeCongestion(placeId, current).toInt(),
142-
byTimePercent = byTimePercent
145+
standardDay = currentDateTime.dayOfWeek.value-1, // 원래 1:월~7:일인데, 0:월~6일로 변경해서 반환
146+
standardTime = currentDateTime.hour, // 0~23
147+
realTimeCongestionLevel = placeRedisUtil.getTimeCongestion(placeId).toInt(),
148+
congestionsByDay = congestionsByDay,
149+
congestionsByTime = congestionsByTime
143150
)
151+
144152
}
145153

146154
@Transactional(readOnly = false)

src/main/kotlin/busanVibe/busan/domain/place/util/PlaceRedisUtil.kt

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,46 +13,49 @@ class PlaceRedisUtil(
1313

1414
private val log = LoggerFactory.getLogger("busanVibe.busan.domain.place")
1515

16-
// 임의로 혼잡도 생성하여 반환. 레디스 키 값으로 저장함.
17-
// fun getRedisCongestion(placeId: Long?): Int{
18-
//
19-
// val key = "place:congestion:$placeId"
20-
// val randomCongestion = getRandomCongestion().toInt().toString()
21-
//
22-
// redisTemplate.opsForValue()
23-
// .set(key, randomCongestion)
24-
//
25-
// return Integer.parseInt(randomCongestion)
26-
// }
16+
// 현재 시간 기준 혼잡도 구하는 메서드
17+
// 현재에 해당하는 요일과 시간의 혼잡도 반환
18+
fun getTimeCongestion(placeId: Long?):Float{
19+
return getTimeCongestion(placeId, LocalDateTime.now())
20+
}
21+
22+
// [요일, 시간] 으로 혼잡도 구하는 메서드
23+
// day: 1~7
24+
fun getTimeCongestion(placeId: Long?, day: Int, hour: Int): Float{
25+
val now = LocalDateTime.now()
26+
return getTimeCongestion(
27+
placeId,
28+
LocalDateTime.of(
29+
now.year,
30+
now.month,
31+
day,
32+
hour,
33+
now.minute
34+
)
35+
)
36+
}
2737

2838
// 지정 시간 혼잡도 조회
29-
// null이면 현재시간 기준
3039
fun getTimeCongestion(placeId: Long?, dateTime: LocalDateTime?): Float {
3140

41+
// DateTime
3242
val dateTime = dateTime ?: LocalDateTime.now()
3343

34-
val roundedHour = (dateTime.hour / 3) * 3
35-
val key = "place:congestion:$placeId-${dateTime.year}-${dateTime.monthValue}-${dateTime.dayOfMonth}-$roundedHour"
36-
44+
val key = getCongestionRedisKey(placeId, dateTime)
3745
val value = redisTemplate.opsForValue().get(key)
3846

3947
return (if (value != null) {
4048
value.toFloatOrNull() ?: 0
4149
} else {
42-
setPlaceTimeCongestion(placeId, dateTime.withHour(roundedHour))
50+
setPlaceTimeCongestion(placeId, dateTime)
4351
val newValue = redisTemplate.opsForValue().get(key)
4452
newValue?.toFloatOrNull() ?: 0
4553
}) as Float
4654
}
4755

48-
fun getTimeCongestion(placeId: Long?):Float{
49-
return getTimeCongestion(placeId, LocalDateTime.now())
50-
}
51-
5256
// 시간 혼잡도 설정
5357
private fun setPlaceTimeCongestion(placeId: Long?, dateTime: LocalDateTime) {
54-
val roundedHour = (dateTime.hour / 3) * 3
55-
val key = "place:congestion:$placeId-${dateTime.year}-${dateTime.monthValue}-${dateTime.dayOfMonth}-$roundedHour"
58+
val key = getCongestionRedisKey(placeId, dateTime)
5659
val congestion = getRandomCongestion().toString()
5760
val success = redisTemplate.opsForValue().setIfAbsent(key, congestion, Duration.ofHours(24))
5861

@@ -65,9 +68,11 @@ class PlaceRedisUtil(
6568
}
6669

6770
// 혼잡도 생성 (1.0 ~ 5.0 사이의 Float)
68-
private fun getRandomCongestion(): Float {
69-
return (Math.random() * 4 + 1).toFloat()
70-
}
71+
private fun getRandomCongestion(): Float = (Math.random() * 4 + 1).toFloat()
72+
7173

74+
// redis에 저장할 key 생성
75+
private fun getCongestionRedisKey(placeId: Long?, dateTime: LocalDateTime): String
76+
= "place:congestion:${placeId}-${dateTime.dayOfWeek}-${dateTime.hour}"
7277

7378
}

0 commit comments

Comments
 (0)