Skip to content

Commit

Permalink
Merge pull request #6 from Nexters/feature/1-api-get-ski-resorts
Browse files Browse the repository at this point in the history
[#1] 스키장 정보 조회 API 개발
  • Loading branch information
jun108059 authored Sep 27, 2024
2 parents 16f1ee1 + 7f64c56 commit 0560c12
Show file tree
Hide file tree
Showing 17 changed files with 459 additions and 2 deletions.
12 changes: 11 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
kotlin("jvm") version "1.9.25"
kotlin("plugin.spring") version "1.9.25"
kotlin("plugin.jpa") version "1.9.25"
id("org.springframework.boot") version "3.3.4"
id("io.spring.dependency-management") version "1.1.6"
}
Expand All @@ -20,10 +21,19 @@ repositories {

dependencies {
implementation("org.springframework.boot:spring-boot-starter")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation("org.springframework.boot:spring-boot-starter-test")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
testImplementation("org.mockito:mockito-core:4.11.0")
testImplementation("org.springframework.boot:spring-boot-starter-test") {
exclude(module = "mockito-core")
}
testImplementation("io.mockk:mockk:1.13.12")
testImplementation("com.ninja-squad:springmockk:4.0.2")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit5")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
runtimeOnly("com.mysql:mysql-connector-j")
}

kotlin {
Expand Down
2 changes: 2 additions & 0 deletions src/main/kotlin/nexters/weski/WeskiApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ package nexters.weski

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.data.jpa.repository.config.EnableJpaAuditing

@SpringBootApplication
@EnableJpaAuditing
class WeskiApplication

fun main(args: Array<String>) {
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/nexters/weski/common/BaseEntity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package nexters.weski.common

import jakarta.persistence.*
import org.springframework.data.annotation.CreatedDate
import org.springframework.data.annotation.LastModifiedDate
import org.springframework.data.jpa.domain.support.AuditingEntityListener
import java.time.LocalDateTime

@MappedSuperclass
@EntityListeners(AuditingEntityListener::class)
abstract class BaseEntity {

@CreatedDate
@Column(updatable = false)
var createdAt: LocalDateTime? = null
private set

@LastModifiedDate
var updatedAt: LocalDateTime? = null
private set
}
43 changes: 43 additions & 0 deletions src/main/kotlin/nexters/weski/ski_resort/SkiResort.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package nexters.weski.ski_resort

import jakarta.persistence.*
import nexters.weski.common.BaseEntity
import nexters.weski.slope.Slope
import nexters.weski.webcam.Webcam

@Entity
@Table(name = "ski_resorts")
data class SkiResort(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val resortId: Long = 0,

val name: String,

@Enumerated(EnumType.STRING)
val status: ResortStatus,

val openingDate: java.time.LocalDate? = null,

val closingDate: java.time.LocalDate? = null,

val openSlopes: Int = 0,

val totalSlopes: Int = 0,

val dayOperatingHours: String? = null,
val nightOperatingHours: String? = null,
val lateNightOperatingHours: String? = null,
val dawnOperatingHours: String? = null,
val midnightOperatingHours: String? = null,

@OneToMany(mappedBy = "skiResort")
val slopes: List<Slope> = emptyList(),

@OneToMany(mappedBy = "skiResort")
val webcams: List<Webcam> = emptyList()
) : BaseEntity()

enum class ResortStatus {
운영중, 운영종료, 예정
}
16 changes: 16 additions & 0 deletions src/main/kotlin/nexters/weski/ski_resort/SkiResortController.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nexters.weski.ski_resort

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/ski-resorts")
class SkiResortController(
private val skiResortService: SkiResortService
) {
@GetMapping
fun getAllSkiResorts(): List<SkiResortResponseDto> {
return skiResortService.getAllSkiResortsAndWeather()
}
}
25 changes: 25 additions & 0 deletions src/main/kotlin/nexters/weski/ski_resort/SkiResortDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package nexters.weski.ski_resort

data class SkiResortDto(
val resortId: Long,
val name: String,
val status: ResortStatus,
val openingDate: String?,
val closingDate: String?,
val openSlopes: Int,
val totalSlopes: Int
) {
companion object {
fun fromEntity(entity: SkiResort): SkiResortDto {
return SkiResortDto(
resortId = entity.resortId,
name = entity.name,
status = entity.status,
openingDate = entity.openingDate?.toString(),
closingDate = entity.closingDate?.toString(),
openSlopes = entity.openSlopes,
totalSlopes = entity.totalSlopes
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nexters.weski.ski_resort

import org.springframework.data.jpa.repository.JpaRepository

interface SkiResortRepository : JpaRepository<SkiResort, Long>
44 changes: 44 additions & 0 deletions src/main/kotlin/nexters/weski/ski_resort/SkiResortResponseDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package nexters.weski.ski_resort

import nexters.weski.weather.CurrentWeather
import nexters.weski.weather.DailyWeather
import nexters.weski.weather.SimpleCurrentWeatherDto
import nexters.weski.weather.WeeklyWeatherDto

data class SkiResortResponseDto(
val resortId: Long,
val name: String,
val status: String,
val openSlopes: Int,
val currentWeather: SimpleCurrentWeatherDto,
val weeklyWeather: List<WeeklyWeatherDto>
) {
companion object {
fun fromEntity(
skiResort: SkiResort,
currentWeather: CurrentWeather?,
weeklyWeather: List<DailyWeather>
): SkiResortResponseDto {
return SkiResortResponseDto(
resortId = skiResort.resortId,
name = skiResort.name,
status = skiResort.status.name,
openSlopes = skiResort.openSlopes,
currentWeather = currentWeather?.let {
SimpleCurrentWeatherDto(
temperature = it.temperature,
description = it.condition.name
)
} ?: SimpleCurrentWeatherDto(0, "정보 없음"),
weeklyWeather = weeklyWeather.map {
WeeklyWeatherDto(
day = it.dayOfWeek,
maxTemperature = it.maxTemp,
minTemperature = it.minTemp,
description = it.dayCondition.name
)
}
)
}
}
}
22 changes: 22 additions & 0 deletions src/main/kotlin/nexters/weski/ski_resort/SkiResortService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package nexters.weski.ski_resort

import nexters.weski.weather.CurrentWeatherRepository
import nexters.weski.weather.DailyWeatherRepository
import org.springframework.stereotype.Service

@Service
class SkiResortService(
private val skiResortRepository: SkiResortRepository,
private val currentWeatherRepository: CurrentWeatherRepository,
private val dailyWeatherRepository: DailyWeatherRepository
) {
fun getAllSkiResortsAndWeather(): List<SkiResortResponseDto> {
val skiResorts = skiResortRepository.findAll()
return skiResorts.map { skiResort ->
val currentWeather = currentWeatherRepository.findBySkiResortResortId(skiResort.resortId)
val weeklyWeather = dailyWeatherRepository.findAllBySkiResortResortId(skiResort.resortId)

SkiResortResponseDto.fromEntity(skiResort, currentWeather, weeklyWeather)
}
}
}
26 changes: 26 additions & 0 deletions src/main/kotlin/nexters/weski/weather/CurrentWeather.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package nexters.weski.weather

import jakarta.persistence.*
import nexters.weski.common.BaseEntity
import nexters.weski.ski_resort.SkiResort

@Entity
@Table(name = "current_weather")
data class CurrentWeather(
@Id
val resortId: Long,

val temperature: Int,
val maxTemp: Int,
val minTemp: Int,
val feelsLike: Int,
val description: String,

@Enumerated(EnumType.STRING)
val condition: WeatherCondition,

@OneToOne
@MapsId
@JoinColumn(name = "resort_id")
val skiResort: SkiResort
) : BaseEntity()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package nexters.weski.weather

import org.springframework.data.jpa.repository.JpaRepository

interface CurrentWeatherRepository : JpaRepository<CurrentWeather, Long> {
fun findBySkiResortResortId(resortId: Long): CurrentWeather?
}
30 changes: 30 additions & 0 deletions src/main/kotlin/nexters/weski/weather/DailyWeather.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package nexters.weski.weather

import jakarta.persistence.*
import nexters.weski.common.BaseEntity
import nexters.weski.ski_resort.SkiResort
import java.time.LocalDate

@Entity
@Table(name = "daily_weather")
data class DailyWeather(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,

val forecastDate: LocalDate,
val dayOfWeek: String,
val precipitationChance: Int,
val maxTemp: Int,
val minTemp: Int,

@Enumerated(EnumType.STRING)
val dayCondition: WeatherCondition,

@Enumerated(EnumType.STRING)
val nightCondition: WeatherCondition,

@ManyToOne
@JoinColumn(name = "resort_id")
val skiResort: SkiResort
) : BaseEntity()
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package nexters.weski.weather

import org.springframework.data.jpa.repository.JpaRepository

interface DailyWeatherRepository : JpaRepository<DailyWeather, Long> {
fun findAllBySkiResortResortId(resortId: Long): List<DailyWeather>
}
Loading

0 comments on commit 0560c12

Please sign in to comment.