From 565b1bf24bd7959090f7a9c54ab4007b8b635742 Mon Sep 17 00:00:00 2001 From: Kim Doo Hyeon Date: Wed, 19 Feb 2025 05:16:25 +0900 Subject: [PATCH] =?UTF-8?q?[ALL]=20=EC=9D=B4=EA=B2=83=EC=A0=80=EA=B2=83=20?= =?UTF-8?q?#43?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 요양보호사 요청 목록 api 수정 및 적합도 추가 --- .../controller/MatchingController.java | 3 +- .../GetMatchingSeniorListResponse.java | 7 +- .../repository/MatchingRepository.java | 2 + .../matching/service/MatchingService.java | 253 +++++++++--------- .../senior/service/RecommendService.java | 15 +- .../young/blaybus/util/enums/CareStyle.java | 10 +- 6 files changed, 152 insertions(+), 138 deletions(-) diff --git a/src/main/java/young/blaybus/domain/matching/controller/MatchingController.java b/src/main/java/young/blaybus/domain/matching/controller/MatchingController.java index 191c0b4..9e1193d 100644 --- a/src/main/java/young/blaybus/domain/matching/controller/MatchingController.java +++ b/src/main/java/young/blaybus/domain/matching/controller/MatchingController.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import young.blaybus.api_response.ApiResponse; @@ -53,7 +54,7 @@ public ApiResponse get() { content = @Content(schema = @Schema(implementation = GetMatchingSeniorListResponse.class)) ) }) - public ApiResponse getMatchingSeniorList() { + public ApiResponse> getMatchingSeniorList() { return ApiResponse.onSuccess(matchingService.getMatchingSeniorList()); } diff --git a/src/main/java/young/blaybus/domain/matching/controller/response/GetMatchingSeniorListResponse.java b/src/main/java/young/blaybus/domain/matching/controller/response/GetMatchingSeniorListResponse.java index c12ce6f..c2849de 100644 --- a/src/main/java/young/blaybus/domain/matching/controller/response/GetMatchingSeniorListResponse.java +++ b/src/main/java/young/blaybus/domain/matching/controller/response/GetMatchingSeniorListResponse.java @@ -2,8 +2,6 @@ import io.swagger.v3.oas.annotations.media.Schema; import lombok.*; -import young.blaybus.domain.address.Address; -import young.blaybus.util.enums.CareStyle; import young.blaybus.util.enums.DayOfWeek; import java.util.List; @@ -17,7 +15,7 @@ public class GetMatchingSeniorListResponse { @Schema(description = "어르신 ID") - private String seniorId; + private long seniorId; @Schema(description = "프로필 사진") private String profileUrl; @@ -39,4 +37,7 @@ public class GetMatchingSeniorListResponse { @Schema(description = "케어 스타일") private String careStyle; + + @Schema(description = "적합도") + private int fitness; } diff --git a/src/main/java/young/blaybus/domain/matching/repository/MatchingRepository.java b/src/main/java/young/blaybus/domain/matching/repository/MatchingRepository.java index 0534a6a..4c9dae3 100644 --- a/src/main/java/young/blaybus/domain/matching/repository/MatchingRepository.java +++ b/src/main/java/young/blaybus/domain/matching/repository/MatchingRepository.java @@ -4,9 +4,11 @@ import young.blaybus.domain.matching.Matching; import java.util.List; +import young.blaybus.domain.matching.enums.MatchingStatus; public interface MatchingRepository extends JpaRepository { Matching findBySenior_IdAndMember_Id(Long senior_id, String member_id); + List findByMember_IdAndStatus(String memberId, MatchingStatus status); List findByMember_Id(String memberId); List findBySenior_Id(Long seniorId); } diff --git a/src/main/java/young/blaybus/domain/matching/service/MatchingService.java b/src/main/java/young/blaybus/domain/matching/service/MatchingService.java index 2b284a9..5237059 100644 --- a/src/main/java/young/blaybus/domain/matching/service/MatchingService.java +++ b/src/main/java/young/blaybus/domain/matching/service/MatchingService.java @@ -3,6 +3,8 @@ import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import young.blaybus.api_response.exception.GeneralException; +import young.blaybus.api_response.status.ErrorStatus; import young.blaybus.domain.matching.Matching; import young.blaybus.domain.matching.controller.request.PatchStatusRequest; import young.blaybus.domain.matching.controller.response.*; @@ -12,7 +14,9 @@ import young.blaybus.domain.member.repository.MemberRepository; import young.blaybus.domain.member.security.SecurityUtils; import young.blaybus.domain.senior.Senior; +import young.blaybus.domain.senior.SeniorDay; import young.blaybus.domain.senior.repository.SeniorRepository; +import young.blaybus.domain.senior.service.RecommendService; import young.blaybus.util.enums.DayOfWeek; import java.time.LocalDateTime; @@ -26,137 +30,140 @@ @RequiredArgsConstructor public class MatchingService { - private final MemberRepository memberRepository; - private final SeniorRepository seniorRepository; - private final MatchingRepository matchingRepository; - - // 매칭 요청 - @Transactional - public void matchingRequest(String workerId, long seniorId) { - Member member = memberRepository.findById(workerId).orElse(null); - Senior senior = seniorRepository.findById(seniorId).orElse(null); - - Matching matching = Matching.builder() - .senior(senior) - .member(member) - .status(MatchingStatus.PENDING) - .createdTime(LocalDateTime.now()) - .build(); - - matchingRepository.save(matching); - } - - // 매칭 현황 조회 (특정) - @Transactional - public GetMatchingStatistics getMatching() { - String workerId = SecurityUtils.getCurrentMemberName(); - Member member = memberRepository.findById(workerId).orElse(null); - if (member != null) { - List matching = matchingRepository.findByMember_Id(member.getId()); - - AtomicInteger fullMatchingCount = new AtomicInteger(); - AtomicInteger acceptance = new AtomicInteger(); - AtomicInteger refusal = new AtomicInteger(); - AtomicInteger tuning = new AtomicInteger(); - - matching.forEach(m -> { - switch (m.getStatus()) { - case ACCEPTED -> acceptance.getAndIncrement(); - case REJECTED -> refusal.getAndIncrement(); - case TUNE_REQUESTED -> tuning.getAndIncrement(); - } - fullMatchingCount.getAndIncrement(); - }); - - return GetMatchingStatistics.builder() - .fullMatching(fullMatchingCount.get()) - .acceptance(acceptance.get()) - .refusal(refusal.get()) - .tuning(tuning.get()) - .build(); + private final MemberRepository memberRepository; + private final SeniorRepository seniorRepository; + private final MatchingRepository matchingRepository; + + private static final String emojiRegex = "[\uD83C-\uDBFF\uDC00-\uDFFF\u2600-\u26FF]+"; + private final RecommendService recommendService; + + // 매칭 요청 + @Transactional + public void matchingRequest(String workerId, long seniorId) { + Member member = memberRepository.findById(workerId).orElse(null); + Senior senior = seniorRepository.findById(seniorId).orElse(null); + + Matching matching = Matching.builder() + .senior(senior) + .member(member) + .status(MatchingStatus.PENDING) + .createdTime(LocalDateTime.now()) + .build(); + + matchingRepository.save(matching); + } + + // 매칭 현황 조회 (특정) + @Transactional + public GetMatchingStatistics getMatching() { + String workerId = SecurityUtils.getCurrentMemberName(); + Member member = memberRepository.findById(workerId).orElse(null); + if (member != null) { + List matching = matchingRepository.findByMember_Id(member.getId()); + + AtomicInteger fullMatchingCount = new AtomicInteger(); + AtomicInteger acceptance = new AtomicInteger(); + AtomicInteger refusal = new AtomicInteger(); + AtomicInteger tuning = new AtomicInteger(); + + matching.forEach(m -> { + switch (m.getStatus()) { + case ACCEPTED -> acceptance.getAndIncrement(); + case REJECTED -> refusal.getAndIncrement(); + case TUNE_REQUESTED -> tuning.getAndIncrement(); } - - return null; + fullMatchingCount.getAndIncrement(); + }); + + return GetMatchingStatistics.builder() + .fullMatching(fullMatchingCount.get()) + .acceptance(acceptance.get()) + .refusal(refusal.get()) + .tuning(tuning.get()) + .build(); } - // 매칭 현황 어르신 리스트 조회 -> 요양보호사 쪽에서 어르신 매칭 요청 조회 - @Transactional - public List getMatchingSeniorList() { - String workerId = SecurityUtils.getCurrentMemberName(); - List matching = matchingRepository.findByMember_Id(workerId); - - List responseList = new ArrayList<>(); + return null; + } + + // 매칭 현황 어르신 리스트 조회 -> 요양보호사 쪽에서 어르신 매칭 요청 조회 + @Transactional + public List getMatchingSeniorList() { + Member worker = memberRepository.findById(SecurityUtils.getCurrentMemberName()) + .orElseThrow(() -> new GeneralException(ErrorStatus.KEY_NOT_EXIST)); + List matching = matchingRepository.findByMember_IdAndStatus(worker.getId(), MatchingStatus.PENDING); + + List responseList = new ArrayList<>(); + matching.forEach(m -> { + Senior senior = m.getSenior(); + List days = senior.getDayList().stream().map(SeniorDay::getDay).toList(); + + responseList.add( + GetMatchingSeniorListResponse.builder() + .seniorId(senior.getId()) + .profileUrl(senior.getProfileUrl()) + .seniorName(senior.getName()) + .address(senior.getAddress()) + .seniorDay(days) + .startTime(senior.getStartTime().format(DateTimeFormatter.ofPattern("a HH:mm").withLocale(Locale.forLanguageTag("ko")))) + .endTime(senior.getEndTime().format(DateTimeFormatter.ofPattern("HH:mm").withLocale(Locale.forLanguageTag("ko")))) + .careStyle(senior.getCareStyle().getValue().replaceAll(emojiRegex, "").strip()) + .fitness(recommendService.calculateFitness(worker, senior)) + .build() + ); + }); + + return responseList; + } + + // 매칭 상태 수정 + @Transactional + public void matchingStatusPatch(PatchStatusRequest statusRequest) { + String workerId = SecurityUtils.getCurrentMemberName(); + Matching matching = matchingRepository.findBySenior_IdAndMember_Id(Long.parseLong(statusRequest.seniorId()), workerId); + + Matching matchingUpdateObject = Matching.builder() + .id(matching.getId()) + .senior(matching.getSenior()) + .member(matching.getMember()) + .status(statusRequest.status()) + .build(); + + matchingRepository.save(matchingUpdateObject); + } + + // 매칭중인 어르신 목록 조회 + @Transactional + public GetProgressMatchingSeniorList getMatchingSeniors() { + String adminId = SecurityUtils.getCurrentMemberName(); + Member member = memberRepository.findById(adminId).orElse(null); + + List seniorsList = new ArrayList<>(); + if (member != null) { + List center = seniorRepository.findByCenterId(member.getCenter().getId()); + center.forEach(s -> { + List matching = matchingRepository.findBySenior_Id(s.getId()); matching.forEach(m -> { - List days = new ArrayList<>(); - m.getSenior().getDayList().forEach(day -> { - days.add(day.getDay()); - }); - - responseList.add( - GetMatchingSeniorListResponse.builder() - .seniorId(String.valueOf(m.getSenior().getId())) - .profileUrl(m.getSenior().getProfileUrl()) - .seniorName(m.getSenior().getName()) - .address(m.getSenior().getAddress()) - .seniorDay(days) - .startTime(m.getSenior().getStartTime().format(DateTimeFormatter.ofPattern("a HH:mm").withLocale(Locale.forLanguageTag("ko")))) - .endTime(m.getSenior().getEndTime().format(DateTimeFormatter.ofPattern("HH:mm").withLocale(Locale.forLanguageTag("ko")))) - .careStyle(m.getSenior().getCareStyle().getValue()) - .build() + if (m.getStatus().equals(MatchingStatus.PENDING)) { + seniorsList.add( + GetProgressMatchingSeniors.builder() + .seniorId(String.valueOf(s.getId())) + .profileUrl(s.getProfileUrl()) + .name(s.getName()) + .sex(s.getSex().name()) + .birthday(s.getBirthday().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))) + .address(s.getAddress()) + .build() ); + } }); + }); - return responseList; } - // 매칭 상태 수정 - @Transactional - public void matchingStatusPatch(PatchStatusRequest statusRequest) { - String workerId = SecurityUtils.getCurrentMemberName(); - Matching matching = matchingRepository.findBySenior_IdAndMember_Id(Long.parseLong(statusRequest.seniorId()), workerId); - - Matching matchingUpdateObject = Matching.builder() - .id(matching.getId()) - .senior(matching.getSenior()) - .member(matching.getMember()) - .status(statusRequest.status()) - .build(); - - matchingRepository.save(matchingUpdateObject); - } - - // 매칭중인 어르신 목록 조회 - @Transactional - public GetProgressMatchingSeniorList getMatchingSeniors() { - String adminId = SecurityUtils.getCurrentMemberName(); - Member member = memberRepository.findById(adminId).orElse(null); - - List seniorsList = new ArrayList<>(); - if (member != null) { - List center = seniorRepository.findByCenterId(member.getCenter().getId()); - center.forEach(s -> { - List matching = matchingRepository.findBySenior_Id(s.getId()); - matching.forEach(m -> { - if (m.getStatus().equals(MatchingStatus.PENDING)) { - seniorsList.add( - GetProgressMatchingSeniors.builder() - .seniorId(String.valueOf(s.getId())) - .profileUrl(s.getProfileUrl()) - .name(s.getName()) - .sex(s.getSex().name()) - .birthday(s.getBirthday().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"))) - .address(s.getAddress()) - .build() - ); - } - }); - }); - - } - - return GetProgressMatchingSeniorList.builder() - .seniorList(seniorsList) - .build(); - } + return GetProgressMatchingSeniorList.builder() + .seniorList(seniorsList) + .build(); + } } 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 b3b1019..bbb9bc2 100644 --- a/src/main/java/young/blaybus/domain/senior/service/RecommendService.java +++ b/src/main/java/young/blaybus/domain/senior/service/RecommendService.java @@ -64,7 +64,7 @@ public ListRecommendResponse getRecommendList(Long seniorId) { .startTime(jobSearch.getStartTime()) .endTime(jobSearch.getEndTime()) .careStyle(member.getCareStyle().getValue()) - .fitness(calculateFitness(member, jobSearch, senior)) + .fitness(calculateFitness(member, senior)) .build() ); } @@ -76,21 +76,24 @@ public ListRecommendResponse getRecommendList(Long seniorId) { .build(); } - private int calculateFitness(Member member, JobSearch jobSearch, Senior senior) { + public int calculateFitness(Member member, Senior senior) { double fitness = 0.0; + JobSearch jobSearch = jobSearchRepository.findByMemberId(member.getId()).orElse(null); JobSeek jobSeek = jobSeekRepository.findBySenior(senior); // 거리 : 0km 최고점, 350km 최하점 → 30점 만점 fitness += 30; - Coordinate memberGeocoding = mapService.geocoding(member.getAddress().toString()); - Coordinate seniorGeocoding = mapService.geocoding(senior.getAddress()); - Double distance = mapService.getDistance(memberGeocoding, seniorGeocoding); + // todo 429 시 로직 추가 +// Coordinate memberGeocoding = mapService.geocoding(member.getAddress().toString()); +// Coordinate seniorGeocoding = mapService.geocoding(senior.getAddress()); +// Double distance = mapService.getDistance(memberGeocoding, seniorGeocoding); double maxDistance = 350_000; - fitness -= Math.min(30, distance * 30 / maxDistance); +// fitness -= Math.min(30, distance * 30 / maxDistance); // 요일 → (노인의 희망 요일이 보호사의 요일과 겹치는 개수) * 15 / (노인의 희망 요일 개수) 점 → 15점 만점 + assert jobSearch != null; List memberDayList = jobSearch.getDayList().stream().map(JobSearchDay::getDay).toList(); List seniorDayList = senior.getDayList().stream().map(SeniorDay::getDay).toList(); int intersectCount = memberDayList.stream() diff --git a/src/main/java/young/blaybus/util/enums/CareStyle.java b/src/main/java/young/blaybus/util/enums/CareStyle.java index 0e1ed80..b9693b5 100644 --- a/src/main/java/young/blaybus/util/enums/CareStyle.java +++ b/src/main/java/young/blaybus/util/enums/CareStyle.java @@ -7,11 +7,11 @@ @RequiredArgsConstructor public enum CareStyle { - STYLE1("📖 메뉴얼과 규칙을 중요시하는 꼼꼼형"), - STYLE2("😌 조용하고 신뢰있게 돕는 차분형"), - STYLE3("⚖️ 필요에 따라 유연하게 조정하는 균형형"), - STYLE4("🤝 감정에 공감하는 정서 교감형"), - STYLE5("🧒 친근한 가족같이 적극적인 돌봄"); + STYLE1("📖 메뉴얼과 규칙을 중요시하는 꼼꼼형"), + STYLE2("😌 조용하고 신뢰있게 돕는 차분형"), + STYLE3("⚖️ 필요에 따라 유연하게 조정하는 균형형"), + STYLE4("🤝 감정에 공감하는 정서 교감형"), + STYLE5("🧒 친근한 가족같이 적극적인 돌봄"); private final String value; }