diff --git a/src/main/java/young/blaybus/domain/job_search/controller/JobSearchController.java b/src/main/java/young/blaybus/domain/job_search/controller/JobSearchController.java index 8a856f6..e44c40c 100644 --- a/src/main/java/young/blaybus/domain/job_search/controller/JobSearchController.java +++ b/src/main/java/young/blaybus/domain/job_search/controller/JobSearchController.java @@ -25,10 +25,13 @@ public ApiResponse createJobSearch(@RequestBody @Valid CreateJobSearchRequest return ApiResponse.onSuccess(); } - @GetMapping("/{member-id}") + @GetMapping("/{member-id}/{senior-id}") @Operation(summary = "회원 ID로 구직 정보 조회") - public ApiResponse getJobSearch(@PathVariable("member-id") String memberId) { - return ApiResponse.onSuccess(jobSearchService.getJobSearch(memberId)); + public ApiResponse getJobSearch( + @PathVariable("member-id") String memberId, + @PathVariable("senior-id") Long seniorId + ) { + return ApiResponse.onSuccess(jobSearchService.getJobSearch(memberId, seniorId)); } @PatchMapping("/{job-search-id}") diff --git a/src/main/java/young/blaybus/domain/job_search/response/DetailJobSearchResponse.java b/src/main/java/young/blaybus/domain/job_search/response/DetailJobSearchResponse.java index 8ae439f..d843188 100644 --- a/src/main/java/young/blaybus/domain/job_search/response/DetailJobSearchResponse.java +++ b/src/main/java/young/blaybus/domain/job_search/response/DetailJobSearchResponse.java @@ -1,7 +1,10 @@ package young.blaybus.domain.job_search.response; import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Locale; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Builder.Default; @@ -9,7 +12,9 @@ import lombok.NoArgsConstructor; import java.util.List; +import lombok.Setter; import young.blaybus.domain.certificate.controller.response.ListCertificateDto; +import young.blaybus.util.enums.CareStyle; @Builder @Getter @@ -21,16 +26,20 @@ public class DetailJobSearchResponse { private Long jobSearchId; @Schema(description = "근무 시작 시간") - private String startTime; + private LocalTime startTime; @Schema(description = "근무 종료 시간") - private String endTime; + private LocalTime endTime; + + @Schema(description = "돌봄 스타일") + private CareStyle careStyle; @Schema(description = "희망 급여") private Integer salary; + @Default @Schema(description = "근무 가능 지역 목록") - private List jobSearchAreas; + private List jobSearchAreas = new ArrayList<>(); @Schema(description = "근무 가능 요일 목록") private List dayList; @@ -48,4 +57,18 @@ public class DetailJobSearchResponse { @Schema(description = "한 줄 소개") private String introduction; + @Setter + @Schema(description = "적합도") + private Integer fitness; + + public String getStartTime() { + return startTime.format(DateTimeFormatter.ofPattern("a HH:mm").withLocale(Locale.forLanguageTag("ko"))); + } + public String getEndTime() { + return endTime.format(DateTimeFormatter.ofPattern("HH:mm").withLocale(Locale.forLanguageTag("ko"))); + } + public String getCareStyle() { + String emojiRegex = "[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u26FF]+"; + return careStyle.getValue().replaceAll(emojiRegex, "").strip(); + } } diff --git a/src/main/java/young/blaybus/domain/job_search/service/JobSearchService.java b/src/main/java/young/blaybus/domain/job_search/service/JobSearchService.java index f464946..2e24856 100644 --- a/src/main/java/young/blaybus/domain/job_search/service/JobSearchService.java +++ b/src/main/java/young/blaybus/domain/job_search/service/JobSearchService.java @@ -20,6 +20,9 @@ import young.blaybus.domain.job_search.response.JobSearchAreaResponse; import young.blaybus.domain.member.Member; import young.blaybus.domain.member.repository.MemberRepository; +import young.blaybus.domain.senior.Senior; +import young.blaybus.domain.senior.repository.SeniorRepository; +import young.blaybus.domain.senior.service.RecommendService; import young.blaybus.util.enums.DayOfWeek; import java.time.LocalDateTime; @@ -34,6 +37,8 @@ public class JobSearchService { private final JobSearchRepository jobSearchRepository; private final MemberRepository memberRepository; private final CertificateRepository certificateRepository; + private final SeniorRepository seniorRepository; + private final RecommendService recommendService; @Transactional public void createJobSearch(CreateJobSearchRequest jobSearchRequest) { @@ -78,9 +83,11 @@ public void updateJobSearch(Long jobSearchId, UpdateJobSearchRequest request) { } @Transactional - public DetailJobSearchResponse getJobSearch(String memberId) { + public DetailJobSearchResponse getJobSearch(String memberId, Long seniorId) { Member member = memberRepository.findById(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus.NOT_FOUND, "존재하지 않는 회원 ID입니다.")); + Senior senior = seniorRepository.findById(seniorId) + .orElseThrow(() -> new GeneralException(ErrorStatus.NOT_FOUND, "존재하지 않는 어르신 ID입니다.")); JobSearch jobSearch = jobSearchRepository.findByMemberId(memberId) .orElseThrow(() -> new GeneralException(ErrorStatus.NOT_FOUND, "해당 회원의 구직 정보가 존재하지 않습니다.")); @@ -108,8 +115,9 @@ public DetailJobSearchResponse getJobSearch(String memberId) { return DetailJobSearchResponse.builder() .jobSearchId(jobSearch.getId()) - .startTime(jobSearch.getStartTime().toString()) - .endTime(jobSearch.getEndTime().toString()) + .startTime(jobSearch.getStartTime()) + .endTime(jobSearch.getEndTime()) + .careStyle(member.getCareStyle()) .salary(jobSearch.getSalary()) .jobSearchAreas(jobSearchAreaResponses) .dayList(dayList) @@ -117,6 +125,7 @@ public DetailJobSearchResponse getJobSearch(String memberId) { .career(member.getCareer()) .careerPeriod(member.getCareerPeriod()) .introduction(member.getIntroduction()) + .fitness(recommendService.calculateFitness(member, senior)) .build(); } } diff --git a/src/main/java/young/blaybus/domain/senior/controller/response/ListRecommendDto.java b/src/main/java/young/blaybus/domain/senior/controller/response/ListRecommendDto.java index 72f70c2..55fe47e 100644 --- a/src/main/java/young/blaybus/domain/senior/controller/response/ListRecommendDto.java +++ b/src/main/java/young/blaybus/domain/senior/controller/response/ListRecommendDto.java @@ -29,6 +29,9 @@ public class ListRecommendDto { @Schema(description = "프로필 사진") private String profileUrl; + @Schema(description = "주소") + private String address; + @Setter @Schema(description = "희망 요일 목록") private List dayList; diff --git a/src/main/java/young/blaybus/domain/senior/service/RecommendService.java b/src/main/java/young/blaybus/domain/senior/service/RecommendService.java index f45833d..13cea16 100644 --- a/src/main/java/young/blaybus/domain/senior/service/RecommendService.java +++ b/src/main/java/young/blaybus/domain/senior/service/RecommendService.java @@ -57,6 +57,7 @@ public ListRecommendResponse getRecommendList(Long seniorId) { ListRecommendDto.builder() .memberId(member.getId()) .name(member.getName()) + .address(member.getAddress().toString()) .profileUrl(member.getProfileUrl()) .dayList(jobSearch.getDayList().stream().map(JobSearchDay::getDay).toList()) .startTime(jobSearch.getStartTime()) @@ -84,8 +85,12 @@ public int calculateFitness(Member member, Senior senior) { try { fitness += 30; Coordinate memberGeocoding = mapService.geocoding(member.getAddress().toString()); + if (memberGeocoding == null) throw new GeneralException(ErrorStatus.INTERNAL_ERROR); Coordinate seniorGeocoding = mapService.geocoding(senior.getAddress()); + if (seniorGeocoding == null) throw new GeneralException(ErrorStatus.INTERNAL_ERROR); Double distance = mapService.getDistance(memberGeocoding, seniorGeocoding); + if (distance == null) throw new GeneralException(ErrorStatus.INTERNAL_ERROR); + double maxDistance = 350_000; fitness -= Math.min(30, distance * 30 / maxDistance); } catch (Exception e) { // API 무료 요청 횟수 초과 시 diff --git a/src/main/java/young/blaybus/map/service/MapService.java b/src/main/java/young/blaybus/map/service/MapService.java index 1785748..4206dd1 100644 --- a/src/main/java/young/blaybus/map/service/MapService.java +++ b/src/main/java/young/blaybus/map/service/MapService.java @@ -57,29 +57,40 @@ public class MapService { * 주소 -> 위도/경도 변환 */ public Coordinate geocoding(String address) { - GeocodingResponse response = skClient.geocoding( - appKey, version, address, addressFlag, coordType, count - ); + try { + GeocodingResponse response = skClient.geocoding( + appKey, version, address, addressFlag, coordType, count + ); + return response.getCoordinateInfo().getCoordinate().get(0); + } catch (Exception e) { + return null; + } - return response.getCoordinateInfo().getCoordinate().get(0); } /** * 좌표 간 거리 계산 */ public Double getDistance(Coordinate start, Coordinate end) { - String requestBody = String.format( - "{\"origins\":[{\"lon\":\"%f\",\"lat\":\"%f\"}],\"destinations\":[{\"lon\":\"%f\",\"lat\":\"%f\"}]}", - start.getLon(), start.getLat(), end.getLon(), end.getLat() - ); - - MatrixResponse matrix = skClient.matrix(appKey, version, requestBody); - return matrix.getMatrix().get(0).getDistance(); + try { + String requestBody = String.format( + "{\"origins\":[{\"lon\":\"%f\",\"lat\":\"%f\"}],\"destinations\":[{\"lon\":\"%f\",\"lat\":\"%f\"}]}", + start.getLon(), start.getLat(), end.getLon(), end.getLat() + ); + MatrixResponse matrix = skClient.matrix(appKey, version, requestBody); + return matrix.getMatrix().get(0).getDistance(); + } catch (Exception e) { + return null; + } } public ListPoiResponse getPoiList(SearchPoiRequest request) { - return skClient.poi(appKey, version, request.address()); + try { + return skClient.poi(appKey, version, request.address()); + } catch (Exception e) { + return null; + } } public void readMapExcel() {