diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeApi.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeApi.java new file mode 100644 index 0000000..5fa22e1 --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeApi.java @@ -0,0 +1,32 @@ +package com.softeer5.uniro_backend.node.controller; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; + +import com.softeer5.uniro_backend.node.dto.GetBuildingResDTO; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; + +@Tag(name = "노드(코어노드, 서브노드, 건물노드) 관련 Api") +public interface NodeApi { + @Operation(summary = "건물 노드 조회") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "건물 노드 조회 성공"), + @ApiResponse(responseCode = "400", description = "EXCEPTION(임시)", content = @Content), + }) + ResponseEntity> getBuildings( + @PathVariable("univId") Long univId, + @RequestParam(value = "level", required = false, defaultValue = "1") int level, + @RequestParam(value = "left-up-lng") double leftUpLng, + @RequestParam(value = "left-up-lat") double leftUpLat, + @RequestParam(value = "right-down-lng") double rightDownLng, + @RequestParam(value = "right-down-lat") double rightDownLat + ); +} diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeController.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeController.java new file mode 100644 index 0000000..46c1662 --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/controller/NodeController.java @@ -0,0 +1,37 @@ +package com.softeer5.uniro_backend.node.controller; + +import java.util.List; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.softeer5.uniro_backend.node.dto.GetBuildingResDTO; +import com.softeer5.uniro_backend.node.service.NodeService; + +import lombok.RequiredArgsConstructor; + +@RestController +@RequiredArgsConstructor +public class NodeController implements NodeApi { + private final NodeService nodeService; + + @Override + @GetMapping("/{univId}/nodes/buildings") + public ResponseEntity> getBuildings( + @PathVariable("univId") Long univId, + @RequestParam(value = "level", required = false, defaultValue = "1") int level, + @RequestParam(value = "left-up-lng") double leftUpLng, + @RequestParam(value = "left-up-lat") double leftUpLat, + @RequestParam(value = "right-down-lng") double rightDownLng, + @RequestParam(value = "right-down-lat") double rightDownLat + ) { + + List buildingResDTOS = nodeService.getBuildings(univId, level, leftUpLng, leftUpLat, + rightDownLng, rightDownLat); + return ResponseEntity.ok().body(buildingResDTOS); + } + +} diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/BuildingNode.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/BuildingNode.java new file mode 100644 index 0000000..3b4d726 --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/BuildingNode.java @@ -0,0 +1,17 @@ +package com.softeer5.uniro_backend.node.dto; + +import com.softeer5.uniro_backend.node.entity.Building; +import com.softeer5.uniro_backend.node.entity.Node; + +import lombok.Getter; + +@Getter +public class BuildingNode { + private final Building building; + private final Node node; + + public BuildingNode(Building building, Node node) { + this.building = building; + this.node = node; + } +} diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/GetBuildingResDTO.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/GetBuildingResDTO.java new file mode 100644 index 0000000..6f0b94e --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/dto/GetBuildingResDTO.java @@ -0,0 +1,37 @@ +package com.softeer5.uniro_backend.node.dto; + +import java.util.Map; + +import com.softeer5.uniro_backend.node.entity.Building; +import com.softeer5.uniro_backend.node.entity.Node; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Schema(name = "GetBuildingResDTO", description = "건물 노드 조회 DTO") +@Getter +@RequiredArgsConstructor +public class GetBuildingResDTO { + + @Schema(description = "노드 id", example = "4") + private final Long nodeId; + + @Schema(description = "건물 노드 좌표", example = "{\"lag\": 127.123456, \"lat\": 37.123456}") + private final Map node; + + private final String buildingName; + + private final String buildingImageUrl; + + private final String phoneNumber; + + private final String address; + + public static GetBuildingResDTO of(Building building, Node node) { + + return new GetBuildingResDTO(node.getId(), node.getXY(), building.getName(), building.getImageUrl(), + building.getPhoneNumber(), building.getAddress()); + } + +} diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/entity/Building.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/entity/Building.java index 1758ae3..09afe5f 100644 --- a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/entity/Building.java +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/entity/Building.java @@ -5,6 +5,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.validation.constraints.NotNull; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; @@ -33,15 +34,12 @@ public class Building { private int level; + @Column(name = "node_id") + @NotNull private Long nodeId; - @Builder - private Building(String phoneNumber, String address, String name, String imageUrl, int level, Long nodeId) { - this.phoneNumber = phoneNumber; - this.address = address; - this.name = name; - this.imageUrl = imageUrl; - this.level = level; - this.nodeId = nodeId; - } + @Column(name = "univ_id") + @NotNull + private Long univId; + } diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/repository/BuildingRepository.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/repository/BuildingRepository.java new file mode 100644 index 0000000..ef57c0e --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/repository/BuildingRepository.java @@ -0,0 +1,23 @@ +package com.softeer5.uniro_backend.node.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import com.softeer5.uniro_backend.node.dto.BuildingNode; +import com.softeer5.uniro_backend.node.entity.Building; + +public interface BuildingRepository extends JpaRepository { + + // 추후에 인덱싱 작업 필요. + @Query(""" + SELECT new com.softeer5.uniro_backend.node.dto.BuildingNode(b, n) + FROM Building b + JOIN FETCH Node n ON b.nodeId = n.id + AND b.univId = :univId + AND b.level >= :level + AND ST_Within(n.coordinates, ST_MakeEnvelope(:lux, :luy, :rdx, :rdy, 4326)) + """) + List findByUnivIdAndLevelWithNode(Long univId, int level, double lux , double luy, double rdx , double rdy); +} diff --git a/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/service/NodeService.java b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/service/NodeService.java new file mode 100644 index 0000000..2e47611 --- /dev/null +++ b/uniro_backend/src/main/java/com/softeer5/uniro_backend/node/service/NodeService.java @@ -0,0 +1,32 @@ +package com.softeer5.uniro_backend.node.service; + +import java.util.List; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.softeer5.uniro_backend.node.dto.BuildingNode; +import com.softeer5.uniro_backend.node.dto.GetBuildingResDTO; +import com.softeer5.uniro_backend.node.repository.BuildingRepository; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class NodeService { + private final BuildingRepository buildingRepository; + + public List getBuildings( + Long univId, int level, + double leftUpLng, double leftUpLat, double rightDownLng , double rightDownLat) { + + List buildingNodes = buildingRepository.findByUnivIdAndLevelWithNode( + univId, level, leftUpLng, leftUpLat, rightDownLng, rightDownLat); + + return buildingNodes.stream() + .map(buildingNode -> GetBuildingResDTO.of(buildingNode.getBuilding(), buildingNode.getNode())) + .toList(); + } + +} diff --git a/uniro_backend/src/main/resources/application-local.yml b/uniro_backend/src/main/resources/application-local.yml index 57fec89..534c39b 100644 --- a/uniro_backend/src/main/resources/application-local.yml +++ b/uniro_backend/src/main/resources/application-local.yml @@ -1,6 +1,6 @@ spring: datasource: - url: jdbc:h2:mem:uniro-local-db;DATABASE_TO_UPPER=FALSE;mode=mysql + url: jdbc:h2:mem:uniro-local-db;mode=mysql driverClassName: org.h2.Driver username: sa password: diff --git a/uniro_backend/src/main/resources/data.sql b/uniro_backend/src/main/resources/data.sql index c05fdbf..fbfa9e7 100644 --- a/uniro_backend/src/main/resources/data.sql +++ b/uniro_backend/src/main/resources/data.sql @@ -18,3 +18,13 @@ VALUES (3, 15.2, ST_GeomFromText('LINESTRING(127.003 37.003, 127.004 37.004)', 4326), 3, 4, 1002, 1, NULL, NULL), (4, 25.7, ST_GeomFromText('LINESTRING(127.004 37.004, 127.005 37.005)', 4326), 4, 5, 1002, 1, '["CURB", "CRACK"]', NULL), (5, 30.0, ST_GeomFromText('LINESTRING(127.005 37.005, 127.006 37.006)', 4326), 5, 6, 1003, NULL, NULL, '["CURB"]'); + +INSERT INTO + building (id, phone_number, address, name, image_url, level, node_id, univ_id) +VALUES + (1, '010-1234-5678', '123 Main St', '공학관', 'http://example.com/image1.jpg', 5, 1, 1001), + (2, '010-2345-6789', '456 Maple Ave', '인문관', 'http://example.com/image2.jpg', 3, 2, 1001), + (3, '010-3456-7890', '789 Oak St', '소프트웨어융합관', 'http://example.com/image3.jpg', 1, 3, 1001), + (4, '010-4567-8901', '101 Pine St', '공대관', 'http://example.com/image4.jpg', 4, 4, 1002), + (5, '010-5678-9012', '202 Cedar Rd', '예술관', 'http://example.com/image5.jpg', 2, 5, 1002), + (6, '010-6789-0123', '303 Birch Ln', '강당', 'http://example.com/image6.jpg', 2, 6, 1003);