Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,6 @@ out/
.vscode/

### application.properties ###
src/main/resources/application-local.yml
src/main/resources/application-local.yml

src/main/resources/google-service-key.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.onebridge.ouch.controller.hospital;

import java.util.List;

import org.springframework.web.bind.annotation.*;

import com.onebridge.ouch.dto.hospital.response.AllDepartmentResponse;
import com.onebridge.ouch.dto.hospital.response.HospitalDetailResponse;
import com.onebridge.ouch.dto.hospital.response.HospitalDistanceResponse;
import com.onebridge.ouch.service.department.DepartmentService;
import com.onebridge.ouch.service.hospital.HospitalDetailService;
import com.onebridge.ouch.service.hospital.HospitalSearchService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@RestController
@Tag(name = "병원 API", description = "병원 관련 API 입니다.")
@RequestMapping("/hospitals")
@RequiredArgsConstructor
public class HospitalController {
private final HospitalSearchService hospitalSearchService;
private final HospitalDetailService hospitalDetailService;
private final DepartmentService departmentService;

@Operation(summary = "거리 순 병원 조회 API", description = "입력된 진료과, 위도(lat), 경도(lng)를 기준으로 병원 목록을 거리 순으로 조회합니다. "
+ "진료과를 입력하지 않으면 입력된 위도, 경도를 기준으로 모든 병원 목록을 거리 순으로 조회합니다. 위도, 경도는 필수로 입력해야 합니다. ")
@GetMapping("/search")
public List<HospitalDistanceResponse> searchHospitals(
@RequestParam(required = false) String department,
@RequestParam Double lat,
@RequestParam Double lng,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size
) {
return hospitalSearchService.searchHospitals(department, lat, lng, page, size);
}

@Operation(summary = "병원 상세 조회 API", description = "입력된 병원 고유ID를 통해 병원 상세 정보를 조회합니다.")
@GetMapping("/{ykiho}")
public HospitalDetailResponse getHospitalDetail(@PathVariable String ykiho) {
return hospitalDetailService.getHospitalDetail(ykiho);
}

@Operation(summary = "진료과 목록 조회 API", description = "모든 진료과 목록을 조회합니다.")
@GetMapping("/departments")
public List<AllDepartmentResponse> getDepartments() {
return departmentService.getAllDepartments();
}
}
22 changes: 0 additions & 22 deletions src/main/java/com/onebridge/ouch/domain/Department.java

This file was deleted.

60 changes: 43 additions & 17 deletions src/main/java/com/onebridge/ouch/domain/Hospital.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,57 @@
package com.onebridge.ouch.domain;

import java.util.ArrayList;
import java.util.List;

import com.onebridge.ouch.domain.common.BaseEntity;
import com.onebridge.ouch.domain.mapping.HospitalDepartment;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Hospital extends BaseEntity {
public class Hospital {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
//@Column(name = "암호화요양기호")
private String ykiho; // 암호화요양기호 (PK)

//@Column(name = "요양기관명")
private String name; // 병원 이름

//@Column(name = "종별코드명")
private String type; // 종별코드명(병원/의원/종합병원 등)

//@Column(name = "시도코드명")
private String sido; // 시/도명

//@Column(name = "시군구코드명")
private String sigungu; // 시/군/구명

//@Column(name = "읍면동")
private String eupmyeondong; // 읍면동

//@Column(name = "우편번호")
private String zipcode; // 우편번호

//@Column(name = "주소")
private String address; // 주소

//@Column(name = "전화번호")
private String tel; // 전화번호

@Column(nullable = false, length = 50)
private String name;
//@Column(name = "좌표(X)")
private Double lat; // 좌표(X) = 위도

@Column(nullable = false, length = 100)
private String address;
//@Column(name = "좌표(Y)")
private Double lng; // 좌표(Y) = 경도

@OneToMany(mappedBy = "hospital", cascade = CascadeType.ALL, orphanRemoval = true)
private List<HospitalDepartment> hospitalDepartmentList = new ArrayList<>();
// @Id
// @GeneratedValue(strategy = GenerationType.IDENTITY)
// private Long id;
//
// @Column(nullable = false, length = 50)
// private String name;
//
// @Column(nullable = false, length = 100)
// private String address;
//
// @OneToMany(mappedBy = "hospital", cascade = CascadeType.ALL, orphanRemoval = true)
// private List<HospitalDepartment> hospitalDepartmentList = new ArrayList<>();
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
package com.onebridge.ouch.domain.mapping;

import com.onebridge.ouch.domain.Hospital;
import com.onebridge.ouch.domain.Department;
import com.onebridge.ouch.domain.common.BaseEntity;

import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class HospitalDepartment extends BaseEntity {
public class HospitalDepartment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
private String ykiho; // 암호화요양기호 (병원 식별자)
private Long departmentCode; // 진료과목코드
private String departmentName; // 진료과목명
private Integer specialistCount; // 전문의 수

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "hospital_id")
private Hospital hospital;
// 병원-진료과 unique 인덱스 (ykiho + departmentCode) 추가 권장
// @Table(uniqueConstraints = {@UniqueConstraint(columnNames = {"ykiho", "departmentCode"})})
}
17 changes: 17 additions & 0 deletions src/main/java/com/onebridge/ouch/domain/tempDomain/Department.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.onebridge.ouch.domain;


import jakarta.persistence.*;
import lombok.*;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Department {

@Id
private Long code; // 진료과목코드(PK, 필요 없으면 생략)
private String nameKr; // 진료과목 한글명
private String nameEn; // 진료과목 영문명
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.onebridge.ouch.dto.hospital.response;

import lombok.Getter;

@Getter
public class AllDepartmentResponse {
private Long code;
private String nameKr;
private String nameEn;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.onebridge.ouch.dto.hospital.response;

import java.util.List;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class HospitalDetailResponse {
private String ykiho;
private String name;
private String type; // 종별코드명
private String zipcode;
private String address;
private Double lat;
private Double lng;
private String tel;
private List<DepartmentInfo> departments;

// Getter/Setter
@Getter
@Setter
public static class DepartmentInfo {
private String departmentName;
private Integer specialistCount; // 전문의 수

// Getter/Setter
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.onebridge.ouch.dto.hospital.response;

import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class HospitalDistanceResponse {
private String ykiho;
private String name;
private String address;
private String tel;
private Double lat;
private Double lng;
private Double distance; //km
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.onebridge.ouch.repository.hospital;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.onebridge.ouch.domain.mapping.HospitalDepartment;

@Repository
public interface HospitalDepartmentRepository extends JpaRepository<HospitalDepartment, Long> {

List<HospitalDepartment> findByYkiho(String ykiho);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.onebridge.ouch.repository.hospital;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import com.onebridge.ouch.domain.Hospital;

@Repository
public interface HospitalRepository extends JpaRepository<Hospital, String> {

// 전체 병원 거리순 정렬 (진료과 미입력시)
@Query(value =
"SELECT h.ykiho, h.name, h.address, h.tel, h.lat, h.lng, " +
" (6371 * acos(cos(radians(:lat)) * cos(radians(h.lat)) " +
" * cos(radians(h.lng) - radians(:lng)) + sin(radians(:lat)) * sin(radians(h.lat)))) as distance " +
"FROM hospital h " +
"WHERE h.lat IS NOT NULL AND h.lng IS NOT NULL " +
"ORDER BY distance ASC " +
"LIMIT :limit OFFSET :offset",
nativeQuery = true)
List<Object[]> findAllOrderByDistance(
@Param("lat") double lat,
@Param("lng") double lng,
@Param("limit") int limit,
@Param("offset") int offset
);

// 진료과 기반 병원 거리순 정렬 (병원-진료과 조인)
@Query(value =
"SELECT h.ykiho, h.name, h.address, h.tel, h.lat, h.lng, " +
" (6371 * acos(cos(radians(:lat)) * cos(radians(h.lat)) " +
" * cos(radians(h.lng) - radians(:lng)) + sin(radians(:lat)) * sin(radians(h.lat)))) as distance " +
"FROM hospital h " +
"JOIN hospital_department hd ON h.ykiho = hd.ykiho " +
"WHERE hd.department_name = :departmentName AND h.lat IS NOT NULL AND h.lng IS NOT NULL " +
"ORDER BY distance ASC " +
"LIMIT :limit OFFSET :offset",
nativeQuery = true)
List<Object[]> findByDepartmentOrderByDistance(
@Param("departmentName") String departmentName,
@Param("lat") double lat,
@Param("lng") double lng,
@Param("limit") int limit,
@Param("offset") int offset
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.onebridge.ouch.service.department;

import java.io.InputStream;
import java.util.List;

import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.onebridge.ouch.dto.hospital.response.AllDepartmentResponse;

import jakarta.annotation.PostConstruct;

@Service
public class DepartmentService {
private List<AllDepartmentResponse> departmentList;

@PostConstruct
public void init() throws Exception {
ObjectMapper mapper = new ObjectMapper();
InputStream input = new ClassPathResource("data/department.json").getInputStream();
departmentList = mapper.readValue(input, new TypeReference<List<AllDepartmentResponse>>() {});
}

public List<AllDepartmentResponse> getAllDepartments() {
return departmentList;
}
}
Loading