Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 도로명 주소 API 호출 기능 생성 #92

Merged
merged 1 commit into from
Dec 5, 2024
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
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ subprojects {
// s3
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.1.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-s3'

implementation 'org.springframework.cloud:spring-cloud-starter-openfeign:4.0.3'
implementation 'org.springframework.cloud:spring-cloud-commons:4.0.3'
}

// QueryDSL 추가
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package pothole_solution.core.domain.pothole.dto.request;

import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
Expand All @@ -9,34 +10,30 @@
import pothole_solution.core.domain.pothole.entity.Pothole;
import pothole_solution.core.domain.pothole.entity.Progress;

import java.util.Random;

@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ReqPotRegPotMngrServDto {
@NotNull(message = "위도의 값은 반드시 존재해야 합니다.")
private double lat;

@NotNull(message = "경도의 값은 반드시 존재해야 합니다.")
private double lon;

@Builder
public ReqPotRegPotMngrServDto(double lat, double lon) {
this.lat = lat;
this.lon = lon;
}
@NotNull(message = "중요도 값은 반드시 존재해야 합니다.")
private int importance;

@NotNull(message = "위험도 값은 반드시 존재해야 합니다.")
private int dangerous;

public Pothole toPothole() {
GeometryFactory geometryFactory = new GeometryFactory();

Integer randomImportance = new Random().nextInt(101);
Integer randomDangerous = new Random().nextInt(101);

return Pothole.builder()
.roadName("강남로 1")
.point(geometryFactory.createPoint(new Coordinate(lon, lat)))
.importance(randomImportance)
.dangerous(randomDangerous)
.importance(importance)
.dangerous(dangerous)
.processStatus(Progress.REGISTER)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@NoArgsConstructor
public class RespPotDetsInfoPotMngrCntrDto {
private Long potholeId;
private String roadName;
private String roadAddress;
private double lat;
private double lon;
private String thumbnail;
Expand All @@ -28,7 +28,7 @@ public class RespPotDetsInfoPotMngrCntrDto {
@Builder
public RespPotDetsInfoPotMngrCntrDto(Pothole pothole, List<RespPotHistGetPotMngrCntrDto> respPotHistGetPotMngrCntrDtoList) {
this.potholeId = pothole.getPotholeId();
this.roadName = pothole.getRoadName();
this.roadAddress = pothole.getRoadAddress();
this.lat = pothole.getPoint().getY();
this.lon = pothole.getPoint().getX();
this.thumbnail = pothole.getThumbnail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@NoArgsConstructor
public class RespPotSimInfoPotMngrCntrDto {
private Long potholeId;
private String roadName;
private String roadAddress;
private double lat;
private double lon;
private String thumbnail;
Expand All @@ -21,7 +21,7 @@ public class RespPotSimInfoPotMngrCntrDto {
@Builder
public RespPotSimInfoPotMngrCntrDto(Pothole pothole) {
this.potholeId = pothole.getPotholeId();
this.roadName = pothole.getRoadName();
this.roadAddress = pothole.getRoadAddress();
this.lat = pothole.getPoint().getY();
this.lon = pothole.getPoint().getX();
this.thumbnail = pothole.getThumbnail();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ public class Pothole extends BaseTimeEntity {
private Long potholeId;

@Column(length = 50)
private String roadName;

private String addressName;
private String roadAddress; // 전체 도로명 주소
private String roadName; // 도로명
private String roadNumber; // 도로 번호
private String zipCode; // 우편 번호

@Column(nullable = false, columnDefinition = "geography(Point, 4326)")
private Point point;
Expand All @@ -31,25 +32,22 @@ public class Pothole extends BaseTimeEntity {
private String thumbnail;

private Integer importance;
private Integer dangerous;

@Column(nullable = false, length = 5)
@Convert(converter = ProgressEnumConverter.class)
private Progress processStatus;

private Integer dangerous;

@OneToMany(mappedBy = "pothole", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PotholeHistory> potholeHistories = new ArrayList<>();

@Builder
public Pothole(String roadName, String addressName, Point point, String thumbnail, Integer importance, Progress processStatus, Integer dangerous) {
this.roadName = roadName;
this.addressName = addressName;
public Pothole(Point point, String thumbnail, Integer importance, Progress processStatus, Integer dangerous) {
this.point = point;
this.thumbnail = thumbnail;
this.importance = importance;
this.processStatus = processStatus;
this.dangerous = dangerous;
this.processStatus = processStatus;
}

public void changeProgress(Progress processStatus) {
Expand All @@ -63,4 +61,11 @@ public void createThumbnail(String thumbnail) {
public void changeThumbnail(String newThumbnail) {
this.thumbnail = newThumbnail;
}

public void initAddress(String roadAddress, String roadName, String zipCode, String roadNumber) {
this.roadAddress = roadAddress;
this.roadName = roadName;
this.zipCode = zipCode;
this.roadNumber = roadNumber;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pothole_solution.core.domain.pothole.entity;

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

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class RoadAddress {
private String zipcode;
private String text;
private Structure structure;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class Structure {
private String level0;
private String level1;
private String level2;
private String level3;
private String level4L;
private String level4LC;
private String level4A;
private String level4AC;
private String level5;
private String detail;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package pothole_solution.core.domain.pothole.entity;

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

import java.util.List;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class RoadAddressSearchApiResponse {
private Response response;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class Response {
private Service service;
private String status;
private List<RoadAddress> result;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class Service {
private String name;
private String version;
private String operation;
private String time;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ private BooleanBuilder getRoadNameFilter(String roadName) {

// 도로명 입력
if (roadName != null && !roadName.isBlank()) {
booleanBuilder.and(pothole.roadName.eq(roadName));
booleanBuilder.and(pothole.roadAddress.eq(roadName));
}

return booleanBuilder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package pothole_solution.core.domain.pothole.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import pothole_solution.core.domain.pothole.entity.RoadAddressSearchApiResponse;

@FeignClient(value= "search", url = "https://api.vworld.kr")
public interface RoadAddressSearchApi {

@GetMapping(value = "/req/address",produces = MediaType.APPLICATION_JSON_VALUE)
RoadAddressSearchApiResponse getRoadAddress(@RequestParam("point") String point,
@RequestParam("key") String key,
@RequestParam("service") String service,
@RequestParam("request") String request,
@RequestParam("crs") String crs,
@RequestParam("type") String type,
@RequestParam("simple") boolean simple
);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package pothole_solution.core.domain.pothole.service;

import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import pothole_solution.core.domain.pothole.entity.RoadAddress;
import pothole_solution.core.domain.pothole.entity.RoadAddressSearchApiResponse;

import static pothole_solution.core.global.exception.CustomException.INVALID_PARAMETER;

@Service
@RequiredArgsConstructor
public class RoadAddressSearchService {
private final RoadAddressSearchApi roadAddressSearchApi;

public RoadAddress getRoadAddress(String point){
RoadAddressSearchApiResponse response = roadAddressSearchApi.getRoadAddress(
point,
"9BFAD946-FBB2-3B7A-9179-82007C7B8D57",
"address",
"getAddress",
"epsg:4326",
"ROAD",
true
);

if (response.getResponse().getStatus().equals("ERROR")) {
throw INVALID_PARAMETER;
}

return response.getResponse().getResult().get(0);
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package pothole_solution.core.global.config;

import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import pothole_solution.core.global.util.formatter.LocalDateFormatter;

@Configuration
@EnableFeignClients(basePackages = {"pothole_solution.core.domain.pothole.service"})
public class AppConfig {
@Bean
public LocalDateFormatter localDateFormatter() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,8 @@
import pothole_solution.core.domain.pothole.dto.response.RespPotDetsInfoPotMngrCntrDto;
import pothole_solution.core.domain.pothole.dto.response.RespPotHistGetPotMngrCntrDto;
import pothole_solution.core.domain.pothole.dto.response.RespPotSimInfoPotMngrCntrDto;
import pothole_solution.core.domain.pothole.entity.Pothole;
import pothole_solution.core.domain.pothole.entity.PotholeHistory;
import pothole_solution.core.domain.pothole.entity.PotholeHistoryImage;
import pothole_solution.core.domain.pothole.entity.Progress;
import pothole_solution.core.domain.pothole.entity.*;
import pothole_solution.core.domain.pothole.service.RoadAddressSearchService;
import pothole_solution.core.global.util.response.BaseResponse;
import pothole_solution.manager.service.PotholeHistoryImageManagerService;
import pothole_solution.manager.service.PotholeManagerService;
Expand All @@ -26,12 +24,22 @@
public class PotholeManagerController {
private final PotholeManagerService potholeManagerService;
private final PotholeHistoryImageManagerService potholeHistoryImageManagerService;
private final RoadAddressSearchService roadAddressSearchService;

@PostMapping("/test")
public BaseResponse<RoadAddress> registerPotholeTest(@Valid @RequestBody ReqPotRegPotMngrServDto reqPotRegPotMngrServDto){
String point = reqPotRegPotMngrServDto.getLat() + "," + reqPotRegPotMngrServDto.getLon();
RoadAddress roadAddress = roadAddressSearchService.getRoadAddress(point);

return new BaseResponse<>(roadAddress);
}

//TODO: 엄밀히 따지면 core 쪽에 있어야 되는거 아닌가?
@PostMapping
public BaseResponse<RespPotSimInfoPotMngrCntrDto> registerPothole(@Valid @RequestPart(value = "registerPothole") ReqPotRegPotMngrServDto reqPotRegPotMngrServDto,
@RequestPart(value = "registerPotholeImages") List<MultipartFile> registerPotholeImages){

Pothole pothole = potholeManagerService.registerPothole(reqPotRegPotMngrServDto.toPothole(), registerPotholeImages);
Pothole pothole = potholeManagerService.registerPothole(reqPotRegPotMngrServDto, registerPotholeImages);

return new BaseResponse<>(new RespPotSimInfoPotMngrCntrDto(pothole));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import org.springframework.web.multipart.MultipartFile;
import pothole_solution.core.domain.pothole.dto.PotFltPotMngrServDto;
import pothole_solution.core.domain.pothole.dto.request.ReqPotChgPrgsStusPotMngrServDto;
import pothole_solution.core.domain.pothole.dto.request.ReqPotRegPotMngrServDto;
import pothole_solution.core.domain.pothole.entity.Pothole;

import java.util.List;

public interface PotholeManagerService {
Pothole registerPothole(Pothole pothole, List<MultipartFile> potholeImages);
Pothole registerPothole(ReqPotRegPotMngrServDto reqPotRegPotMngrServDto, List<MultipartFile> potholeImages);

Pothole getPotholeWithPotholeHistoryByPotholeId(Long potholeId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
import org.springframework.web.multipart.MultipartFile;
import pothole_solution.core.domain.pothole.dto.PotFltPotMngrServDto;
import pothole_solution.core.domain.pothole.dto.request.ReqPotChgPrgsStusPotMngrServDto;
import pothole_solution.core.domain.pothole.entity.Pothole;
import pothole_solution.core.domain.pothole.entity.PotholeHistory;
import pothole_solution.core.domain.pothole.entity.PotholeHistoryImage;
import pothole_solution.core.domain.pothole.dto.request.ReqPotRegPotMngrServDto;
import pothole_solution.core.domain.pothole.entity.*;
import pothole_solution.core.domain.pothole.repository.PotholeHistoryImageRepository;
import pothole_solution.core.domain.pothole.repository.PotholeHistoryRepository;
import pothole_solution.core.domain.pothole.repository.PotholeQueryDslRepository;
import pothole_solution.core.domain.pothole.repository.PotholeRepository;
import pothole_solution.core.domain.pothole.service.RoadAddressSearchService;
import pothole_solution.core.infra.s3.ImageService;

import java.util.List;
Expand All @@ -28,10 +28,15 @@ public class PotholeManagerServiceImpl implements PotholeManagerService {
private final PotholeHistoryImageRepository potholeHistoryImageRepository;
private final PotholeQueryDslRepository potholeQueryDslRepository;
private final ImageService imageService;
private final RoadAddressSearchService roadAddressSearchService;

@Override
public Pothole registerPothole(Pothole pothole, List<MultipartFile> registerPotholeImages) {
public Pothole registerPothole(ReqPotRegPotMngrServDto reqPotRegPotMngrServDto, List<MultipartFile> registerPotholeImages) {
// Pothole 저장
Pothole pothole = reqPotRegPotMngrServDto.toPothole();

RoadAddress roadAddress = roadAddressSearchService.getRoadAddress(reqPotRegPotMngrServDto.getLon() + "," + reqPotRegPotMngrServDto.getLat());
pothole.initAddress(roadAddress.getText(), roadAddress.getStructure().getLevel4L(), roadAddress.getZipcode(), roadAddress.getStructure().getLevel4LC());
potholeRepository.save(pothole);

// 포트홀 등록 이미지 S3에 업로드 및 썸네일 설정
Expand Down