Skip to content

Commit

Permalink
Merge pull request #29 from prgrms-be-devcourse/feature/real-time-eme…
Browse files Browse the repository at this point in the history
…rgency-room

[#14] [FEATURE] 실시간 응급실 가용 현황 API 구현
  • Loading branch information
JiwonKKang authored Sep 27, 2024
2 parents cb9b370 + 9824e4a commit 418f013
Show file tree
Hide file tree
Showing 43 changed files with 668 additions and 185 deletions.
115 changes: 57 additions & 58 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,78 +1,77 @@
plugins {
id 'java'
id 'java-library'
id 'org.springframework.boot' version '3.2.7'
id 'io.spring.dependency-management' version '1.1.5'
id 'com.diffplug.spotless' version '6.25.0'
id 'java'
id 'java-library'
id 'org.springframework.boot' version '3.2.7'
id 'io.spring.dependency-management' version '1.1.5'
id 'com.diffplug.spotless' version '6.25.0'
}

allprojects {
repositories {
mavenCentral()
}
repositories {
mavenCentral()
}
}

subprojects {
group = 'com.nbe2'
version = '0.0.1'
sourceCompatibility = '17'

apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.diffplug.spotless'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

test() {
useJUnitPlatform()
}

spotless {
java {
googleJavaFormat().aosp()
importOrder('java', 'javax', 'jakarta', 'org', 'lombok', 'com')
removeUnusedImports()
trimTrailingWhitespace()
endWithNewline()
}
}
group = 'com.nbe2'
version = '0.0.1'
sourceCompatibility = '17'

apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'com.diffplug.spotless'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
}

dependencies {
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

test() {
useJUnitPlatform()
}

spotless {
java {
googleJavaFormat().aosp()
importOrder('java', 'javax', 'jakarta', 'org', 'lombok', 'com')
removeUnusedImports()
trimTrailingWhitespace()
endWithNewline()
}
}
}


tasks.register("addGitPreCommitHook", Copy) {
from 'script/pre-commit'
into '.git/hooks'
from 'script/pre-commit'
into '.git/hooks'
}

bootJar {
enabled = false
enabled = false
}

project(':ea-application') {
bootJar {
enabled = false
}
bootJar {
enabled = false
}

jar {
enabled = false
}
jar {
enabled = false
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import com.nbe2.api.emergencyroom.dto.RealTimeEmergencyRoomResponse;
import com.nbe2.api.global.dto.Response;
import com.nbe2.domain.emergencyroom.Coordinate;
import com.nbe2.domain.emergencyroom.EmergencyRoomService;

@RestController
Expand All @@ -20,12 +21,19 @@ public class EmergencyRoomApi {

private final EmergencyRoomService emergencyRoomService;

@GetMapping("/init")
public Response<Void> init() {
emergencyRoomService.init();
return Response.success("전국 응급실 데이터 저장 완료");
}

@GetMapping("/real-time")
public Response<List<RealTimeEmergencyRoomResponse>> getRealTimeEmergencyRooms(
@RequestParam String region, @RequestParam String subRegion) {

Double longitude, Double latitude) {
List<RealTimeEmergencyRoomResponse> responses =
emergencyRoomService.getRealTimeEmergencyData(region, subRegion).stream()
emergencyRoomService
.getRealTimeEmergencyRooms(Coordinate.of(longitude, latitude))
.stream()
.map(RealTimeEmergencyRoomResponse::from)
.toList();
return Response.success(responses);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.nbe2.api.emergencyroom.dto;

import com.nbe2.domain.emergencyroom.RealTimeEmergencyInfo;
import com.nbe2.domain.emergencyroom.RealTimeEmergencyRoomWithDistance;

public record RealTimeEmergencyRoomResponse(
String hospitalId, // 병원 ID
Expand All @@ -19,27 +19,37 @@ public record RealTimeEmergencyRoomResponse(
boolean isAngiographyAvailable, // 혈관촬영기 가용 여부 (Y: 가능, N: 불가)
boolean isVentilatorAvailable, // 인공호흡기 가용 여부 (Y: 가능, N: 불가)
boolean isIncubatorAvailable, // 인큐베이터 가용 여부 (Y: 가능, N: 불가)
boolean isAmbulanceAvailable // 구급차 가용 여부 (Y: 가능, N: 불가))
) {
boolean isAmbulanceAvailable, // 구급차 가용 여부 (Y: 가능, N: 불가))
double distance) {

public static RealTimeEmergencyRoomResponse from(RealTimeEmergencyInfo realTimeEmergencyInfo) {
public static RealTimeEmergencyRoomResponse from(
RealTimeEmergencyRoomWithDistance realTimeEmergencyRoomWithDistance) {
return new RealTimeEmergencyRoomResponse(
realTimeEmergencyInfo.hospitalId(),
realTimeEmergencyInfo.hospitalName(),
realTimeEmergencyInfo.emergencyPhone(),
realTimeEmergencyInfo.inputDate(),
realTimeEmergencyInfo.availableBeds(),
realTimeEmergencyInfo.operatingRoomBeds(),
realTimeEmergencyInfo.neuroIcuBeds(),
realTimeEmergencyInfo.neonatalIcuBeds(),
realTimeEmergencyInfo.chestIcuBeds(),
realTimeEmergencyInfo.generalIcuBeds(),
realTimeEmergencyInfo.generalWardBeds(),
realTimeEmergencyInfo.isCtAvailable(),
realTimeEmergencyInfo.isMriAvailable(),
realTimeEmergencyInfo.isAngiographyAvailable(),
realTimeEmergencyInfo.isVentilatorAvailable(),
realTimeEmergencyInfo.isIncubatorAvailable(),
realTimeEmergencyInfo.isAmbulanceAvailable());
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().hospitalId(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().hospitalName(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().emergencyPhone(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().inputDate(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().availableBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().operatingRoomBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().neuroIcuBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().neonatalIcuBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().chestIcuBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().generalIcuBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().generalWardBeds(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().isCtAvailable(),
realTimeEmergencyRoomWithDistance.realTimeEmergencyRoomInfo().isMriAvailable(),
realTimeEmergencyRoomWithDistance
.realTimeEmergencyRoomInfo()
.isAngiographyAvailable(),
realTimeEmergencyRoomWithDistance
.realTimeEmergencyRoomInfo()
.isVentilatorAvailable(),
realTimeEmergencyRoomWithDistance
.realTimeEmergencyRoomInfo()
.isIncubatorAvailable(),
realTimeEmergencyRoomWithDistance
.realTimeEmergencyRoomInfo()
.isAmbulanceAvailable(),
realTimeEmergencyRoomWithDistance.distance());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@RequiredArgsConstructor
public enum GlobalErrorCode implements BaseErrorCode {
PERMISSION_DENIED(403, "PERMISSION_DENIED", "해당 API 권한이 없습니다"),
PERMISSION_DENIED(403, "PERMISSION_DENIED_401", "해당 API 권한이 없습니다"),
OTHER_SERVER_BAD_REQUEST(BAD_REQUEST, "AUTH_OTHER_400", "Other server bad request"),
OTHER_SERVER_UNAUTHORIZED(UNAUTHORIZED, "AUTH_OTHER_401", "Other server unauthorized"),
OTHER_SERVER_FORBIDDEN(FORBIDDEN, "AUTH_OTHER_403", "Other server forbidden"),
Expand Down
3 changes: 0 additions & 3 deletions ea-domain/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,5 @@ bootJar {
dependencies {

implementation project(":ea-common")

implementation 'org.springframework:spring-context'
implementation 'org.springframework:spring-tx'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.nbe2.domain.emergencyroom;

import jakarta.persistence.Embeddable;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Embeddable
@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)
@AllArgsConstructor(access = lombok.AccessLevel.PRIVATE)
public final class Coordinate {

private Double longitude;
private Double latitude;

public static Coordinate of(Double longitude, Double latitude) {
return new Coordinate(longitude, latitude);
}

public double distanceTo(Coordinate targetCoordinate) {
final int EARTH_RADIUS_KM = 6371; // 지구의 평균 반지름 (킬로미터 단위)

double lat1 = Math.toRadians(latitude);
double lon1 = Math.toRadians(longitude);
double lat2 = Math.toRadians(targetCoordinate.getLatitude());
double lon2 = Math.toRadians(targetCoordinate.getLongitude());

double deltaLat = lat2 - lat1;
double deltaLon = lon2 - lon1;

double a =
Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2)
+ Math.cos(lat1)
* Math.cos(lat2)
* Math.sin(deltaLon / 2)
* Math.sin(deltaLon / 2);

double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

return Math.round(EARTH_RADIUS_KM * c * 100) / 100.0;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.nbe2.domain.emergencyroom;

public interface CoordinateToRegionConverter {

Region convert(Coordinate coordinate);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.nbe2.domain.emergencyroom;

import java.util.Comparator;
import java.util.List;

import org.springframework.stereotype.Component;

import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class DistanceCalculator {

private final EmergencyRoomReader emergencyRoomReader;

public List<RealTimeEmergencyRoomWithDistance> calculate(
List<RealTimeEmergencyRoomInfo> realTimeEmergencyRoomInfos,
Coordinate currentCoordinate) {

return realTimeEmergencyRoomInfos.stream()
.map(info -> calculateDistance(currentCoordinate, info))
.sorted(Comparator.comparing(RealTimeEmergencyRoomWithDistance::distance))
.toList();
}

private RealTimeEmergencyRoomWithDistance calculateDistance(
Coordinate currentCoordinate, RealTimeEmergencyRoomInfo info) {
EmergencyRoom emergencyRoom = emergencyRoomReader.read(info.hospitalId());
double distance = currentCoordinate.distanceTo(emergencyRoom.getLocation());
return RealTimeEmergencyRoomWithDistance.of(info, distance);
}
}
Loading

0 comments on commit 418f013

Please sign in to comment.