diff --git a/src/main/java/Ness/Backend/domain/main/MainService.java b/src/main/java/Ness/Backend/domain/main/MainService.java index 2929023..744ee97 100644 --- a/src/main/java/Ness/Backend/domain/main/MainService.java +++ b/src/main/java/Ness/Backend/domain/main/MainService.java @@ -11,6 +11,8 @@ import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; @Service @RequiredArgsConstructor @@ -18,15 +20,34 @@ public class MainService { private final ReportService reportService; private final TodoService todoService; - public GetMainDto getMain(Long memberId){ - List scheduleDtos = todoService.getTodo(memberId); - PostFastApiAiRecommendActivityDto activityDtos = reportService.getRecommendActivity(memberId); + try { + CompletableFuture> scheduleFuture = CompletableFuture.supplyAsync(() -> todoService.getTodo(memberId)); + CompletableFuture activityFuture = CompletableFuture.supplyAsync(() -> reportService.getRecommendActivity(memberId)); + CompletableFuture combinedFuture = CompletableFuture.allOf(scheduleFuture, activityFuture); + + // 두 작업이 모두 완료될 때까지 기다린다.(각각 진행되는 것은 맞음, 가장 늦은 작업 완료에 맞춤) + combinedFuture.join(); + List scheduleDtos = scheduleFuture.get(); + PostFastApiAiRecommendActivityDto activityDtos = activityFuture.get(); + return toEntity(scheduleDtos, activityDtos); + } + // 비동기 에러 발생시 동기 처리를 하더라도 메인 API 제공되도록 로직 설정 + catch (Exception exception){ + List scheduleDtos = todoService.getTodo(memberId); + PostFastApiAiRecommendActivityDto activityDtos = reportService.getRecommendActivity(memberId); + return toEntity(scheduleDtos, activityDtos); + } + } + + //Entity -> DTO + public GetMainDto toEntity(List scheduleDtos, PostFastApiAiRecommendActivityDto activityDtos){ return GetMainDto.builder() .recommendText(activityDtos.getAnswer()) .activityList(activityDtos.getActivityList()) .scheduleList(scheduleDtos) .build(); } + } diff --git a/src/main/java/Ness/Backend/domain/report/ReportMemoryRepository.java b/src/main/java/Ness/Backend/domain/report/ReportMemoryRepository.java index 7080734..a7d64aa 100644 --- a/src/main/java/Ness/Backend/domain/report/ReportMemoryRepository.java +++ b/src/main/java/Ness/Backend/domain/report/ReportMemoryRepository.java @@ -12,19 +12,26 @@ public interface ReportMemoryRepository extends JpaRepository findTodayReportMemoryByMember_Id( @Param("memberId") Long memberId); - @Query( value = "SELECT * FROM report_memory " + + + // 특정 맴버의 2주치 생성된 데이터 반환(단, 하루에 만드시 한개씩 반환, 2주치면 최대 14개) + @Query(value = "SELECT * FROM ( " + + "SELECT report_memory.*, ROW_NUMBER() OVER (PARTITION BY DATE(CONVERT_TZ(created_date, '+00:00', '+09:00')) " + + "ORDER BY created_date DESC) as row_num " + + "FROM report_memory " + "WHERE member_id = :memberId " + - "AND created_date >= DATE_SUB(NOW(), INTERVAL 2 WEEK) " + - "ORDER BY created_date ASC", + "AND created_date >= CONVERT_TZ(DATE_SUB(NOW(), INTERVAL 2 WEEK), '+00:00', '+09:00') " + + ") AS subquery " + + "WHERE row_num = 1 " + + "ORDER BY created_date ASC " + + "LIMIT 14", nativeQuery = true) List findTwoWeekUserMemoryByMember_Id( @Param("memberId") Long memberId); - List findReportMemoriesByMember_idAndCreatedDateBetweenOrderByCreatedDateAsc(Long id, ZonedDateTime startOfWeek, ZonedDateTime now); } diff --git a/src/main/java/Ness/Backend/domain/report/ReportService.java b/src/main/java/Ness/Backend/domain/report/ReportService.java index 07aabcf..3c973ad 100644 --- a/src/main/java/Ness/Backend/domain/report/ReportService.java +++ b/src/main/java/Ness/Backend/domain/report/ReportService.java @@ -2,6 +2,9 @@ import Ness.Backend.domain.member.MemberRepository; import Ness.Backend.domain.member.entity.Member; +import Ness.Backend.domain.profile.ProfileRepository; +import Ness.Backend.domain.profile.entity.PersonaType; +import Ness.Backend.domain.profile.entity.Profile; import Ness.Backend.domain.report.dto.request.PostFastApiUserMemoryDto; import Ness.Backend.domain.report.dto.request.PostFastApiUserRecommendActivityDto; import Ness.Backend.domain.report.dto.request.PostFastApiUserTagDto; @@ -37,19 +40,22 @@ public class ReportService { private final FastApiTagApi fastApiTagApi; private final FastApiMemoryApi fastApiMemoryApi; private final MemberRepository memberRepository; + private final ProfileRepository profileRepository; /* 메모리 가져오는 로직 */ - public GetReportMemoryListDto getMemory(Long id){ + public GetReportMemoryListDto getMemory(Long memberId){ + log.info("getMemory called by member: " + memberId); + // 오늘 날짜 가져오기 ZonedDateTime now = getToday(); - ReportMemory reportMemory = reportMemoryRepository.findTodayReportMemoryByMember_Id(id); + List reportMemory = reportMemoryRepository.findTodayReportMemoryByMember_Id(memberId); - if (reportMemory == null){ + if (reportMemory.isEmpty()){ // 오늘치가 없다면 새롭게 생성하기 - String memory = postNewAiMemory(id, now); + String memory = postNewAiMemory(memberId, now); - Member memberEntity = memberRepository.findMemberById(id); + Member memberEntity = memberRepository.findMemberById(memberId); ReportMemory newMemory = ReportMemory.builder() .createdDate(now) @@ -61,7 +67,7 @@ public GetReportMemoryListDto getMemory(Long id){ } // 2주치의 데이터 가져오기 - List reportMemories = reportMemoryRepository.findTwoWeekUserMemoryByMember_Id(id); + List reportMemories = reportMemoryRepository.findTwoWeekUserMemoryByMember_Id(memberId); return createReportMemoryListDto(reportMemories); } @@ -78,10 +84,11 @@ public GetReportMemoryListDto createReportMemoryListDto(List repor return new GetReportMemoryListDto(getReportMemoryDtos); } - public String postNewAiMemory(Long id, ZonedDateTime today){ + public String postNewAiMemory(Long memberId, ZonedDateTime today){ + String persona = getPersona(memberId); PostFastApiUserMemoryDto userDto = PostFastApiUserMemoryDto.builder() - .member_id(id.intValue()) - .user_persona("") + .member_id(memberId.intValue()) + .user_persona(persona) .schedule_datetime_start(today) .schedule_datetime_end(today) .build(); @@ -93,16 +100,18 @@ public String postNewAiMemory(Long id, ZonedDateTime today){ } /* 테그 가져오는 로직 */ - public GetReportTagListDto getTag(Long id){ + public GetReportTagListDto getTag(Long memberId){ + log.info("getTag called by member: " + memberId); + // 오늘 날짜 가져오기 ZonedDateTime now = getToday(); - List reportTags = reportTagRepository.findLastMonthReportTagByMember_Id(id); + List reportTags = reportTagRepository.findLastMonthReportTagByMember_Id(memberId); if (reportTags == null || reportTags.isEmpty()) { - PostFastApiAiTagListDto aiDto = postNewAiTag(id, getToday()); + PostFastApiAiTagListDto aiDto = postNewAiTag(memberId, getToday()); - Member memberEntity = memberRepository.findMemberById(id); + Member memberEntity = memberRepository.findMemberById(memberId); for (PostFastApiAiTagDto tag : aiDto.getTags()) { ReportTag reportTag = ReportTag.builder() @@ -113,7 +122,7 @@ public GetReportTagListDto getTag(Long id){ .build(); reportTagRepository.save(reportTag); } - return createReportTagListDto(reportTagRepository.findLastMonthReportTagByMember_Id(id)); + return createReportTagListDto(reportTagRepository.findLastMonthReportTagByMember_Id(memberId)); } else { return createReportTagListDto(reportTags); } @@ -132,14 +141,15 @@ public GetReportTagListDto createReportTagListDto(List reportTags){ return new GetReportTagListDto(getReportTagDtos); } - public PostFastApiAiTagListDto getAiTag(Long id){ - return postNewAiTag(id, getToday()); + public PostFastApiAiTagListDto getAiTag(Long memberId){ + return postNewAiTag(memberId, getToday()); } - public PostFastApiAiTagListDto postNewAiTag(Long id, ZonedDateTime today){ + public PostFastApiAiTagListDto postNewAiTag(Long memberId, ZonedDateTime today){ + String persona = getPersona(memberId); PostFastApiUserTagDto userDto = PostFastApiUserTagDto.builder() - .member_id(id.intValue()) - .user_persona("") + .member_id(memberId.intValue()) + .user_persona(persona) .schedule_datetime_start(today) .schedule_datetime_end(today) .build(); @@ -150,11 +160,13 @@ public PostFastApiAiTagListDto postNewAiTag(Long id, ZonedDateTime today){ /* 한 줄 추천 및 엑티비티 가져오는 로직 */ public PostFastApiAiRecommendActivityDto getRecommendActivity(Long memberId){ + log.info("getRecommendActivity called by member: " + memberId); + // 오늘 날짜 가져오기 ZonedDateTime now = getToday(); List reportRecommends = reportRecommendRepository.findTodayReportRecommendByMember_Id(memberId); - if(reportRecommends.isEmpty()){ + if(reportRecommends == null || reportRecommends.isEmpty()){ //새로운 한 줄 추천 및 엑티비티 생성하기 PostFastApiAiRecommendActivityDto aiDto = postNewAiRecommend(memberId, now); aiDto.setAnswer(parseAiRecommend(aiDto.getAnswer())); @@ -203,10 +215,11 @@ public PostFastApiAiRecommendActivityDto getRecommendActivity(Long memberId){ } } - public PostFastApiAiRecommendActivityDto postNewAiRecommend(Long id, ZonedDateTime today){ + public PostFastApiAiRecommendActivityDto postNewAiRecommend(Long memberId, ZonedDateTime today){ + String persona = getPersona(memberId); PostFastApiUserRecommendActivityDto userDto = PostFastApiUserRecommendActivityDto.builder() - .member_id(id.intValue()) - .user_persona("") // 빈 문자열은 default + .member_id(memberId.intValue()) + .user_persona(persona) .schedule_datetime_start(today) .schedule_datetime_end(today) .build(); @@ -223,4 +236,19 @@ public ZonedDateTime getToday(){ return ZonedDateTime.now(ZoneId.of("Asia/Seoul")); } + public String getPersona(Long memberId){ + Profile profileEntity = profileRepository.findProfileByMember_Id(memberId); + PersonaType personaType = profileEntity.getPersonaType(); + + String persona = "default"; + if (personaType == PersonaType.HARDNESS){ + persona = "hard"; + } + if (personaType == PersonaType.CALMNESS){ + persona = "calm"; + } + + return persona; + } + } diff --git a/src/main/java/Ness/Backend/domain/todo/TodoService.java b/src/main/java/Ness/Backend/domain/todo/TodoService.java index 0bd3724..1e81cec 100644 --- a/src/main/java/Ness/Backend/domain/todo/TodoService.java +++ b/src/main/java/Ness/Backend/domain/todo/TodoService.java @@ -34,6 +34,8 @@ public class TodoService { /* 일정 관련 한 줄 추천 가져오는 로직 */ public List getTodo(Long memberId){ + log.info("getTodo called by member: " + memberId); + Profile userProfile = profileRepository.findProfileByMember_Id(memberId); // 오늘 날짜 가져오기 ZonedDateTime now = time.getToday();