From 3b7f206ea1e5a41100988c75b030de75b551eea6 Mon Sep 17 00:00:00 2001 From: minjoon-98 <4kmj54321@gmail.com> Date: Wed, 24 Jul 2024 17:16:48 +0900 Subject: [PATCH 1/5] fix: findFastestAnsweredChallenge by Lucky --- .../namanmoo/controller/RecapController.java | 5 +- .../namanmoo/service/AnswerService.java | 5 + .../namanmoo/service/AnswerServiceImpl.java | 90 ++++++++++++++ .../namanmoo/service/ChallengeService.java | 4 - .../service/ChallengeServiceImpl.java | 112 ------------------ 5 files changed, 98 insertions(+), 118 deletions(-) diff --git a/src/main/java/ongjong/namanmoo/controller/RecapController.java b/src/main/java/ongjong/namanmoo/controller/RecapController.java index 0fe6e82..0cbdcb9 100644 --- a/src/main/java/ongjong/namanmoo/controller/RecapController.java +++ b/src/main/java/ongjong/namanmoo/controller/RecapController.java @@ -42,6 +42,7 @@ public class RecapController { private final AwsS3Service awsS3Service; private final FFmpegService ffmpegService; private final SharedFileService sharedFileService; + private final AnswerServiceImpl answerServiceImpl; // 행운이 리스트 @GetMapping("/list") @@ -85,10 +86,10 @@ public ApiResponse>> getStatistics(@RequestParam("lucky mostViewedData.put("challengeTitle", mostViewedChallenge != null ? mostViewedChallenge.getChallengeTitle() : ""); // 모두가 가장 빨리 답한 챌린지 - Challenge fastestAnsweredChallenge = challengeService.findFastestAnsweredChallenge(lucky); + Challenge fastestAnsweredChallenge = answerService.findFastestAnsweredChallenge(lucky); Map fastestAnsweredData = new HashMap<>(); fastestAnsweredData.put("topic", "fastestAnswered"); - fastestAnsweredData.put("topicResult", fastestAnsweredChallenge != null ? challengeService.calculateLatestResponseTime(lucky, fastestAnsweredChallenge) : 0); + fastestAnsweredData.put("topicResult", fastestAnsweredChallenge != null ? answerService.calculateLatestResponseTime(answerService.findAnswersByChallenges(fastestAnsweredChallenge, memberService.findMemberByLoginId())) : 0); fastestAnsweredData.put("challengeId", fastestAnsweredChallenge != null ? fastestAnsweredChallenge.getChallengeId() : ""); fastestAnsweredData.put("challengeType", fastestAnsweredChallenge != null ? fastestAnsweredChallenge.getChallengeType() : ""); fastestAnsweredData.put("challengeNumber", fastestAnsweredChallenge != null ? fastestAnsweredChallenge.getChallengeNum() : ""); diff --git a/src/main/java/ongjong/namanmoo/service/AnswerService.java b/src/main/java/ongjong/namanmoo/service/AnswerService.java index eaa3d83..844ce82 100644 --- a/src/main/java/ongjong/namanmoo/service/AnswerService.java +++ b/src/main/java/ongjong/namanmoo/service/AnswerService.java @@ -1,6 +1,7 @@ package ongjong.namanmoo.service; import ongjong.namanmoo.domain.Family; +import ongjong.namanmoo.domain.Lucky; import ongjong.namanmoo.domain.Member; import ongjong.namanmoo.domain.answer.Answer; import ongjong.namanmoo.domain.challenge.Challenge; @@ -45,6 +46,10 @@ public interface AnswerService { List getAnswersByMember(Long luckyId, int challengeNum1, int challengeNum2, Class dtoClass) throws Exception; + Challenge findFastestAnsweredChallenge(Lucky lucky) throws Exception; + + long calculateLatestResponseTime(List answers); + List getYouthByMember(Long luckyId, int challengeNum1, int challengeNum2) throws Exception; List getAppreciationByMember(Long luckyId, int challengeNum1, int challengeNum2) throws Exception; diff --git a/src/main/java/ongjong/namanmoo/service/AnswerServiceImpl.java b/src/main/java/ongjong/namanmoo/service/AnswerServiceImpl.java index b4493eb..15c96df 100644 --- a/src/main/java/ongjong/namanmoo/service/AnswerServiceImpl.java +++ b/src/main/java/ongjong/namanmoo/service/AnswerServiceImpl.java @@ -14,6 +14,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.text.ParseException; +import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; @@ -322,6 +324,94 @@ public List getAnswersByMember(Long luckyId, int challengeNum1, int c return memberDtoList; } + // 모든 가족 구성원이 가장 빠르게 답한 챌린지를 반환 + @Override + public Challenge findFastestAnsweredChallenge(Lucky lucky) throws Exception { + Family family = lucky.getFamily(); + + // Lucky 기간 동안의 모든 답변 가져오기 + String startDate = lucky.getChallengeStartDate(); + String endDate = DateUtil.getInstance().addDaysToStringDate(startDate, lucky.getLifetime().getDays()); + List answersWithinDateRange = answerRepository.findByMemberFamilyAndCreateDateBetween(family, startDate, endDate); + + // createDate를 기준으로 그룹화 + Map> answersByCreateDate = answersWithinDateRange.stream() + .collect(Collectors.groupingBy(Answer::getCreateDate)); + + Challenge fastestChallenge = null; + long shortestTime = Long.MAX_VALUE; + + for (Map.Entry> entry : answersByCreateDate.entrySet()) { + List answers = entry.getValue(); + + // 모든 가족 구성원이 해당 챌린지에 대해 답변했는지 확인 + if (answers.size() == family.getMembers().size() && + answers.stream().allMatch(answer -> + answer.getAnswerContent() != null && !answer.getAnswerContent().isEmpty() && + answer.getModifiedDate() != null && !answer.getModifiedDate().isEmpty())) { + + // 각 챌린지에 대해 답변 확인 및 가장 늦은 응답 시간 계산 + long timeToAnswer = calculateLatestResponseTime(answers); + log.info("Create Date: " + entry.getKey() + ", Time to answer: " + timeToAnswer); + + if (timeToAnswer < shortestTime) { + shortestTime = timeToAnswer; + fastestChallenge = answers.get(0).getChallenge(); + } + } + } + + log.info("Fastest Challenge ID: " + (fastestChallenge != null ? fastestChallenge.getChallengeId() : "None")); + return fastestChallenge; + } + + // 챌린지에 달린 답변 중, 가장 늦게 달린 답변 시간을 계산 + public long calculateLatestResponseTime(List answers) { + long latestTime = Long.MIN_VALUE; // 해당 챌린지의 가장 늦은 응답시간을 저장할 변수 + + SimpleDateFormat format4 = new SimpleDateFormat(DateUtil.FORMAT_4); + SimpleDateFormat format9 = new SimpleDateFormat(DateUtil.FORMAT_9); + + for (Answer answer : answers) { + try { + String createDate = answer.getCreateDate(); + String modifiedDate = answer.getModifiedDate(); + + if (createDate == null || modifiedDate == null) { + log.warn("답변 ID: {}에서 Null 타임스탬프를 찾았습니다.", answer.getAnswerId()); + continue; + } + + Date createTime = format4.parse(createDate); + Date modifiedTime = format9.parse(modifiedDate); + log.info("답변 수정 시간: {}, 답변 생성 시간: {}", modifiedTime.getTime(), createTime.getTime()); + + long responseTime = Math.abs(modifiedTime.getTime() - createTime.getTime()); // 응답 시간 계산 + log.info("응답 시간: {}", responseTime); + + if (responseTime > latestTime) { + latestTime = responseTime; + } + } catch (ParseException e) { + log.error("답변 ID: {}의 날짜 파싱 에러", answer.getAnswerId(), e); + } + } + + if (latestTime == Long.MIN_VALUE) { + return Long.MAX_VALUE; + } + long totalSeconds = latestTime / 1000; + long totalMinutes = totalSeconds / 60; + long totalHours = totalMinutes / 60; + long days = totalHours / 24; + long seconds = totalSeconds % 60; + long minutes = totalMinutes % 60; + long hours = totalHours % 24; + log.info("가장 늦은 응답 시간: " + days + "일 " + hours + "시간 " + minutes + "분 " + seconds + "초"); + return latestTime; + } + + // DTO 생성 로직을 처리하는 메서드 public MemberDto createDto(Class dtoClass, Member member, String answer1, String answer2) { if (dtoClass == MemberAppreciationDto.class) { diff --git a/src/main/java/ongjong/namanmoo/service/ChallengeService.java b/src/main/java/ongjong/namanmoo/service/ChallengeService.java index 15f3555..5cf446c 100644 --- a/src/main/java/ongjong/namanmoo/service/ChallengeService.java +++ b/src/main/java/ongjong/namanmoo/service/ChallengeService.java @@ -36,10 +36,6 @@ public interface ChallengeService { Challenge findMostViewedChallenge(Lucky lucky) throws Exception; - Challenge findFastestAnsweredChallenge(Lucky lucky) throws Exception; - - long calculateLatestResponseTime(Lucky lucky, Challenge challenge) throws Exception ; - // groupChallenge 조회를 위한 dto (부모와 자식의 challenge 질문 구분하기) GroupChallengeDto filterChallengesByMemberRole(Challenge challenge, Long timeStamp, boolean isComplete, List answers); } diff --git a/src/main/java/ongjong/namanmoo/service/ChallengeServiceImpl.java b/src/main/java/ongjong/namanmoo/service/ChallengeServiceImpl.java index 2ce1bd0..654674b 100644 --- a/src/main/java/ongjong/namanmoo/service/ChallengeServiceImpl.java +++ b/src/main/java/ongjong/namanmoo/service/ChallengeServiceImpl.java @@ -350,116 +350,4 @@ public Challenge findMostViewedChallenge(Lucky lucky) throws Exception { return null; } - // 모든 가족 구성원이 가장 빠르게 답한 챌린지를 반환 - @Override - public Challenge findFastestAnsweredChallenge(Lucky lucky) throws Exception { - Family family = lucky.getFamily(); - List challenges = findRunningChallenges(); // 해당 Lucky의 모든 챌린지 가져오기 - Challenge fastestChallenge = null; - long shortestTime = Long.MAX_VALUE; - - for (Challenge challenge : challenges) { - List relatedChallenges = challengeRepository.findByChallengeNum(challenge.getChallengeNum()); - int totalMembers = family.getMembers().size(); - - // 모든 관련 챌린지에 대해 모든 가족 구성원이 답변을 완료했는지 확인 - boolean allRelatedChallengesAnswered = true; - for (Challenge relatedChallenge : relatedChallenges) { - List relatedAnswers = answerRepository.findByChallengeAndMemberFamily(relatedChallenge, family); - if (relatedAnswers.size() != totalMembers) { - allRelatedChallengesAnswered = false; - break; - } - } - - if (!allRelatedChallengesAnswered) { - continue; - } - - // 각 챌린지에 대해 답변 확인 및 가장 늦은 응답 시간 계산 - for (Challenge relatedChallenge : relatedChallenges) { - List answers = answerRepository.findByChallengeAndMemberFamily(relatedChallenge, family); - log.info("Challenge ID: " + relatedChallenge.getChallengeId() + ", Answer count: " + answers.size()); - - // 해당 챌린지에 대해 모든 가족 구성원이 답변 내용을 입력했는지 확인 - boolean allMembersAnswered = true; - for (Answer answer : answers) { - if (answer.getAnswerContent() == null || answer.getAnswerContent().isEmpty() || answer.getModifiedDate() == null || answer.getModifiedDate().isEmpty()) { - allMembersAnswered = false; - break; - } - } - - if (allMembersAnswered) { - long timeToAnswer = calculateLatestResponseTime(lucky, relatedChallenge); // 챌린지별 가장 늦은 응답 시간 계산 - log.info("Challenge ID: " + relatedChallenge.getChallengeId() + ", Time to answer: " + timeToAnswer); - if (timeToAnswer < shortestTime) { - shortestTime = timeToAnswer; - fastestChallenge = relatedChallenge; - } - } - } - } - log.info("Fastest Challenge ID: " + (fastestChallenge != null ? fastestChallenge.getChallengeId() : "None")); - return fastestChallenge; - } - - // 챌린지에 달린 답변 중, 가장 늦게 달린 답변 시간을 계산 - @Override - public long calculateLatestResponseTime(Lucky lucky, Challenge challenge) throws Exception { - long latestTime = Long.MIN_VALUE; // 해당 챌린지의 가장 늦은 응답시간을 저장할 변수 - List answers = answerRepository.findByChallenge(challenge); - - SimpleDateFormat format4 = new SimpleDateFormat(DateUtil.FORMAT_4); - SimpleDateFormat format9 = new SimpleDateFormat(DateUtil.FORMAT_9); - - for (Member member : lucky.getFamily().getMembers()) { - long latestResponseTimeForMember = Long.MIN_VALUE; // 가족 구성원의 가장 늦은 응답시간을 저장할 변수 - - for (Answer answer : answers) { - if (answer.getMember().equals(member)) { - try { - String createDate = answer.getCreateDate(); - String modifiedDate = answer.getModifiedDate(); - - if (createDate == null || modifiedDate == null) { - log.warn("답변 ID: {}에서 Null 타임스탬프를 찾았습니다.", answer.getAnswerId()); - continue; - } - - Date createTime = format4.parse(createDate); - Date modifiedTime = format9.parse(modifiedDate); - log.info("답변 수정 시간: {}, 답변 생성 시간: {}", modifiedTime.getTime(), createTime.getTime()); - - long responseTime = Math.abs(modifiedTime.getTime() - createTime.getTime()); // 원래라면 수정 날짜가 답변이 열리는 날짜보다 나중이기 때문에 음수가 나올일이 없지만 올바른 시연을 위해 절대값 처리 - log.info("회원 ID: {}, 응답 시간: {}", member.getMemberId(), responseTime); - - if (responseTime > latestResponseTimeForMember) { - latestResponseTimeForMember = responseTime; - } - } catch (ParseException e) { - log.error("답변 ID: {}의 날짜 파싱 에러", answer.getAnswerId(), e); - } - } - } - - if (latestResponseTimeForMember > latestTime) { - latestTime = latestResponseTimeForMember; - } - } - - if (latestTime == Long.MIN_VALUE) { - return Long.MAX_VALUE; - } - long totalSeconds = latestTime / 1000; - long totalMinutes = totalSeconds / 60; - long totalHours = totalMinutes / 60; - long days = totalHours / 24; - long seconds = totalSeconds % 60; - long minutes = totalMinutes % 60; - long hours = totalHours % 24; - log.info("가장 늦은 응답 시간: " + days + "일 " + hours + "시간 " + minutes + "분 " + seconds + "초"); - return latestTime; - } - } From 042f869564bed833dda898a41c5fc208b1c7d744 Mon Sep 17 00:00:00 2001 From: minjoon-98 <4kmj54321@gmail.com> Date: Wed, 24 Jul 2024 20:34:50 +0900 Subject: [PATCH 2/5] chore : Updated the wording of challenge descriptions --- .../namanmoo/service/ChallengeDataInit.java | 88 +++++++++---------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/main/java/ongjong/namanmoo/service/ChallengeDataInit.java b/src/main/java/ongjong/namanmoo/service/ChallengeDataInit.java index 8233a35..123da6e 100644 --- a/src/main/java/ongjong/namanmoo/service/ChallengeDataInit.java +++ b/src/main/java/ongjong/namanmoo/service/ChallengeDataInit.java @@ -25,14 +25,14 @@ public void createChallenges() { // 챌린지 생성 및 추가 challenges.add(createChallenge(1, "자신의 어릴 적 사진을 올려보세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(2, "오늘 하루 중 가장 즐거웠던 순간은 언제였나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(3, "내가 가장 좋아하는 음식과 싫어하는 음식은 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(4, "시간 여행을 한다면 언제로 돌아가고 싶은가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(5, "함께 먹고 싶은 음식 사진을 올려보세요. 이번 주에 먹었던 것 중 가장 맛있었던 것도 좋아요.", ChallengeType.PHOTO)); + challenges.add(createChallenge(2, "오늘 가장 즐거웠던 순간은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(3, "내가 좋아하는 음식과 싫어하는 음식은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(4, "시간 여행을 한다면 언제로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(5, "함께 먹고 싶은 음식 사진을 올려보세요.", ChallengeType.PHOTO)); challenges.add(createChallenge(6, "가장 좋아하는 노래가 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(7, "가족 중 한 명이 갑자기 바퀴벌레 혹은 좀비가 된다면 당신의 반응은?", ChallengeType.NORMAL)); - challenges.add(createChallenge(8, "여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(9, "첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); + challenges.add(createChallenge(7, "가족 중 한 명이 갑자기 바퀴벌레가 된다면 당신의 반응은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(8, "가족과 여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(9, "배우자와의 첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); challenges.add(createChallenge(9, "부모님이 가장 잘 어울린다고 느껴진 순간이 있나요?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(10, "가장 마음에 드는 본인 사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(11, "가족이 가장 듬직했던 순간이 있나요?", ChallengeType.NORMAL)); @@ -51,24 +51,24 @@ public void createChallenges() { challenges.add(createChallenge(21, "가장 좋아하는 가족사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(22, "가족에게 가장 서운했던 순간은?", ChallengeType.NORMAL)); challenges.add(createChallenge(23, "자녀가 가장 자랑스러운 순간은?", ChallengeType.GROUP_PARENT)); - challenges.add(createChallenge(23, "부모님이 가장 멋있었던 적이 있다면?", ChallengeType.GROUP_CHILD)); + challenges.add(createChallenge(23, "부모님이 멋있었던 순간은?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(24, "가장 기억에 남는 가족 여행지와 그 이유는 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(25, "가장 좋아하는 계절은 무엇인가요? 그 계절을 좋아하는 이유는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(25, "가장 좋아하는 계절과 이유는는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(26, "학생 때 졸업 사진을 올려주세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(27, "가족 중에서 가장 요리를 잘 하는 사람은 누구인가요? 그분의 최고 요리는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(27, "가족 중 요리 잘하는 사람과 그 요리는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(28, "가족에게 고마운 점이 있다면 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(29, "가족에게 진심으로 미안하지만 사과하지 못한 일이 있다면 무엇입니까?", ChallengeType.NORMAL)); + challenges.add(createChallenge(29, "가족에게 사과하지 못한 일이 있다면?", ChallengeType.NORMAL)); challenges.add(createChallenge(30, "인생네컷 챌린지!", ChallengeType.FACETIME)); // 한 챌린지 주기 = 30일 challenges.add(createChallenge(31, "자신의 어릴 적 사진을 올려보세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(32, "오늘 하루 중 가장 즐거웠던 순간은 언제였나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(33, "내가 가장 좋아하는 음식과 싫어하는 음식은 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(34, "시간 여행을 한다면 언제로 돌아가고 싶은가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(35, "함께 먹고 싶은 음식 사진을 올려보세요. 이번 주에 먹었던 것 중 가장 맛있었던 것도 좋아요.", ChallengeType.PHOTO)); + challenges.add(createChallenge(32, "오늘 가장 즐거웠던 순간은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(33, "내가 좋아하는 음식과 싫어하는 음식은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(34, "시간 여행을 한다면 언제로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(35, "함께 먹고 싶은 음식 사진을 올려보세요.", ChallengeType.PHOTO)); challenges.add(createChallenge(36, "가장 좋아하는 노래가 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(37, "가족 중 한 명이 갑자기 바퀴벌레 혹은 좀비가 된다면 당신의 반응은?", ChallengeType.NORMAL)); - challenges.add(createChallenge(38, "여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(39, "첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); + challenges.add(createChallenge(37, "가족 중 한 명이 갑자기 바퀴벌레가 된다면 당신의 반응은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(38, "가족과 여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(39, "배우자와의 첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); challenges.add(createChallenge(39, "부모님이 가장 잘 어울린다고 느껴진 순간이 있나요?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(40, "가장 마음에 드는 본인 사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(41, "가족이 가장 듬직했던 순간이 있나요?", ChallengeType.NORMAL)); @@ -87,24 +87,24 @@ public void createChallenges() { challenges.add(createChallenge(51, "가장 좋아하는 가족사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(52, "가족에게 가장 서운했던 순간은?", ChallengeType.NORMAL)); challenges.add(createChallenge(53, "자녀가 가장 자랑스러운 순간은?", ChallengeType.GROUP_PARENT)); - challenges.add(createChallenge(53, "부모님이 가장 멋있었던 적이 있다면?", ChallengeType.GROUP_CHILD)); + challenges.add(createChallenge(53, "부모님이 멋있었던 순간은?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(54, "가장 기억에 남는 가족 여행지와 그 이유는 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(55, "가장 좋아하는 계절은 무엇인가요? 그 계절을 좋아하는 이유는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(55, "가장 좋아하는 계절과 이유는는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(56, "학생 때 졸업 사진을 올려주세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(57, "가족 중에서 가장 요리를 잘 하는 사람은 누구인가요? 그분의 최고 요리는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(57, "가족 중 요리 잘하는 사람과 그 요리는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(58, "가족에게 고마운 점이 있다면 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(59, "가족에게 진심으로 미안하지만 사과하지 못한 일이 있다면 무엇입니까?", ChallengeType.NORMAL)); + challenges.add(createChallenge(59, "가족에게 사과하지 못한 일이 있다면?", ChallengeType.NORMAL)); challenges.add(createChallenge(60, "인생네컷 챌린지!", ChallengeType.FACETIME)); // 한 챌린지 주기 = 30일 challenges.add(createChallenge(61, "자신의 어릴 적 사진을 올려보세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(62, "오늘 하루 중 가장 즐거웠던 순간은 언제였나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(63, "내가 가장 좋아하는 음식과 싫어하는 음식은 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(64, "시간 여행을 한다면 언제로 돌아가고 싶은가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(65, "함께 먹고 싶은 음식 사진을 올려보세요. 이번 주에 먹었던 것 중 가장 맛있었던 것도 좋아요.", ChallengeType.PHOTO)); + challenges.add(createChallenge(62, "오늘 가장 즐거웠던 순간은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(63, "내가 좋아하는 음식과 싫어하는 음식은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(64, "시간 여행을 한다면 언제로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(65, "함께 먹고 싶은 음식 사진을 올려보세요.", ChallengeType.PHOTO)); challenges.add(createChallenge(66, "가장 좋아하는 노래가 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(67, "가족 중 한 명이 갑자기 바퀴벌레 혹은 좀비가 된다면 당신의 반응은?", ChallengeType.NORMAL)); - challenges.add(createChallenge(68, "여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(69, "첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); + challenges.add(createChallenge(67, "가족 중 한 명이 갑자기 바퀴벌레가 된다면 당신의 반응은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(68, "가족과 여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(69, "배우자와의 첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); challenges.add(createChallenge(69, "부모님이 가장 잘 어울린다고 느껴진 순간이 있나요?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(70, "가장 마음에 드는 본인 사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(71, "가족이 가장 듬직했던 순간이 있나요?", ChallengeType.NORMAL)); @@ -123,24 +123,24 @@ public void createChallenges() { challenges.add(createChallenge(81, "가장 좋아하는 가족사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(82, "가족에게 가장 서운했던 순간은?", ChallengeType.NORMAL)); challenges.add(createChallenge(83, "자녀가 가장 자랑스러운 순간은?", ChallengeType.GROUP_PARENT)); - challenges.add(createChallenge(83, "부모님이 가장 멋있었던 적이 있다면?", ChallengeType.GROUP_CHILD)); + challenges.add(createChallenge(83, "부모님이 멋있었던 순간은?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(84, "가장 기억에 남는 가족 여행지와 그 이유는 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(85, "가장 좋아하는 계절은 무엇인가요? 그 계절을 좋아하는 이유는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(85, "가장 좋아하는 계절과 이유는는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(86, "학생 때 졸업 사진을 올려주세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(87, "가족 중에서 가장 요리를 잘 하는 사람은 누구인가요? 그분의 최고 요리는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(87, "가족 중 요리 잘하는 사람과 그 요리는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(88, "가족에게 고마운 점이 있다면 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(89, "가족에게 진심으로 미안하지만 사과하지 못한 일이 있다면 무엇입니까?", ChallengeType.NORMAL)); + challenges.add(createChallenge(89, "가족에게 사과하지 못한 일이 있다면?", ChallengeType.NORMAL)); challenges.add(createChallenge(90, "인생네컷 챌린지!", ChallengeType.FACETIME)); // 한 챌린지 주기 = 30 challenges.add(createChallenge(91, "자신의 어릴 적 사진을 올려보세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(92, "오늘 하루 중 가장 즐거웠던 순간은 언제였나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(93, "내가 가장 좋아하는 음식과 싫어하는 음식은 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(94, "시간 여행을 한다면 언제로 돌아가고 싶은가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(95, "함께 먹고 싶은 음식 사진을 올려보세요. 이번 주에 먹었던 것 중 가장 맛있었던 것도 좋아요.", ChallengeType.PHOTO)); + challenges.add(createChallenge(92, "오늘 가장 즐거웠던 순간은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(93, "내가 좋아하는 음식과 싫어하는 음식은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(94, "시간 여행을 한다면 언제로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(95, "함께 먹고 싶은 음식 사진을 올려보세요.", ChallengeType.PHOTO)); challenges.add(createChallenge(96, "가장 좋아하는 노래가 무엇인가요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(97, "가족 중 한 명이 갑자기 바퀴벌레 혹은 좀비가 된다면 당신의 반응은?", ChallengeType.NORMAL)); - challenges.add(createChallenge(98, "여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); - challenges.add(createChallenge(99, "첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); + challenges.add(createChallenge(97, "가족 중 한 명이 갑자기 바퀴벌레가 된다면 당신의 반응은?", ChallengeType.NORMAL)); + challenges.add(createChallenge(98, "가족과 여행을 간다면 어디로 가고 싶나요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(99, "배우자와의 첫 만남은 어디에서 또는 어떻게 이루어졌나요?", ChallengeType.GROUP_PARENT)); challenges.add(createChallenge(99, "부모님이 가장 잘 어울린다고 느껴진 순간이 있나요?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(100, "가장 마음에 드는 본인 사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(101, "가족이 가장 듬직했던 순간이 있나요?", ChallengeType.NORMAL)); @@ -159,13 +159,13 @@ public void createChallenges() { challenges.add(createChallenge(111, "가장 좋아하는 가족사진을 올려보세요", ChallengeType.PHOTO)); challenges.add(createChallenge(112, "가족에게 가장 서운했던 순간은?", ChallengeType.NORMAL)); challenges.add(createChallenge(113, "자녀가 가장 자랑스러운 순간은?", ChallengeType.GROUP_PARENT)); - challenges.add(createChallenge(113, "부모님이 가장 멋있었던 적이 있다면?", ChallengeType.GROUP_CHILD)); + challenges.add(createChallenge(113, "부모님이 멋있었던 순간은?", ChallengeType.GROUP_CHILD)); challenges.add(createChallenge(114, "가장 기억에 남는 가족 여행지와 그 이유는 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(115, "가장 좋아하는 계절은 무엇인가요? 그 계절을 좋아하는 이유는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(115, "가장 좋아하는 계절과 이유는는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(116, "학생 때 졸업 사진을 올려주세요", ChallengeType.PHOTO)); - challenges.add(createChallenge(117, "가족 중에서 가장 요리를 잘 하는 사람은 누구인가요? 그분의 최고 요리는 무엇인가요?", ChallengeType.NORMAL)); + challenges.add(createChallenge(117, "가족 중 요리 잘하는 사람과 그 요리는 무엇인가요?", ChallengeType.NORMAL)); challenges.add(createChallenge(118, "가족에게 고마운 점이 있다면 무엇입니까?", ChallengeType.NORMAL)); - challenges.add(createChallenge(119, "가족에게 진심으로 미안하지만 사과하지 못한 일이 있다면 무엇입니까?", ChallengeType.NORMAL)); + challenges.add(createChallenge(119, "가족에게 사과하지 못한 일이 있다면?", ChallengeType.NORMAL)); challenges.add(createChallenge(120, "인생네컷 챌린지!", ChallengeType.FACETIME)); // 챌린지를 저장 From 2c401467e04590315229390d5477a717c203fadc Mon Sep 17 00:00:00 2001 From: minjoon-98 <4kmj54321@gmail.com> Date: Wed, 24 Jul 2024 20:35:48 +0900 Subject: [PATCH 3/5] chore : Activated asynchronous functionalities for Spring application --- src/main/java/ongjong/namanmoo/NamanmooApplication.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/ongjong/namanmoo/NamanmooApplication.java b/src/main/java/ongjong/namanmoo/NamanmooApplication.java index 76f5cd5..4466835 100644 --- a/src/main/java/ongjong/namanmoo/NamanmooApplication.java +++ b/src/main/java/ongjong/namanmoo/NamanmooApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.scheduling.annotation.EnableAsync; @SpringBootApplication +@EnableAsync public class NamanmooApplication { public static void main(String[] args) { From df094b0cf9d610366edbc332eece026367ec7a82 Mon Sep 17 00:00:00 2001 From: minjoon-98 <4kmj54321@gmail.com> Date: Wed, 24 Jul 2024 20:37:48 +0900 Subject: [PATCH 4/5] chore : Changed file name settings by removing UUID --- src/main/java/ongjong/namanmoo/service/AwsS3Service.java | 4 +++- src/main/java/ongjong/namanmoo/service/SharedFileService.java | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/ongjong/namanmoo/service/AwsS3Service.java b/src/main/java/ongjong/namanmoo/service/AwsS3Service.java index b06e260..c03f7f4 100644 --- a/src/main/java/ongjong/namanmoo/service/AwsS3Service.java +++ b/src/main/java/ongjong/namanmoo/service/AwsS3Service.java @@ -108,7 +108,9 @@ private String determineFileType(MultipartFile multipartFile) { * @throws IOException 파일 변환 중 발생하는 예외 */ private Optional convertFile(MultipartFile file) throws IOException { - String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); +// String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename(); + String fileName = file.getOriginalFilename(); + assert fileName != null; File convertFile = new File(fileName); if (convertFile.createNewFile()) { diff --git a/src/main/java/ongjong/namanmoo/service/SharedFileService.java b/src/main/java/ongjong/namanmoo/service/SharedFileService.java index 843b0ab..9a305c9 100644 --- a/src/main/java/ongjong/namanmoo/service/SharedFileService.java +++ b/src/main/java/ongjong/namanmoo/service/SharedFileService.java @@ -311,7 +311,8 @@ public void mergeImagesIfNeeded(int challengeNum, Lucky lucky) throws IOExceptio // UUID 생성 및 파일 이름 설정 String uuid = UUID.randomUUID().toString(); - String baseName = "merged-images/" + uuid + "_" + challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; +// String baseName = "merged-images/" + uuid + "_" + challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; + String baseName = "merged-images/" + "life4cut_"+ challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; BufferedImage mergedImage = ImageMerger.mergeImages(selectedImages); // 병합된 이미지를 S3에 업로드 From b2913781af5d958457ef6a4f7d14366d3884f77b Mon Sep 17 00:00:00 2001 From: minjoon-98 <4kmj54321@gmail.com> Date: Wed, 24 Jul 2024 21:41:08 +0900 Subject: [PATCH 5/5] fix: merge image fix --- .../namanmoo/service/SharedFileService.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/main/java/ongjong/namanmoo/service/SharedFileService.java b/src/main/java/ongjong/namanmoo/service/SharedFileService.java index 9a305c9..0e5ed39 100644 --- a/src/main/java/ongjong/namanmoo/service/SharedFileService.java +++ b/src/main/java/ongjong/namanmoo/service/SharedFileService.java @@ -1,5 +1,7 @@ package ongjong.namanmoo.service; +import com.amazonaws.AmazonServiceException; +import com.amazonaws.SdkClientException; import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.services.s3.AmazonS3; @@ -249,18 +251,19 @@ public void mergeImagesIfNeeded(int challengeNum, Lucky lucky) throws IOExceptio } } - // 모든 그룹에 대해 4개 이상의 이미지를 가진 그룹이 있는지 확인 - boolean allGroupsHaveEnoughImages = groupedFiles.values().stream().allMatch(list -> list.size() >= 4); - - if (allGroupsHaveEnoughImages) { - break; // 모든 그룹에 4개 이상의 이미지가 있는 경우 병합을 시작 - } -// // 어떠한 그룹에 대해 4개 이상의 이미지를 가진 그룹이 있는지 확인 -// boolean anyGroupHasEnoughImages = groupedFiles.values().stream().anyMatch(list -> list.size() >= 4); +// // 모든 그룹에 대해 4개 이상의 이미지를 가진 그룹이 있는지 확인 +// boolean allGroupsHaveEnoughImages = groupedFiles.values().stream().allMatch(list -> list.size() >= 4); // -// if (anyGroupHasEnoughImages || System.currentTimeMillis() - startTime > MAX_WAIT_TIME) { -// break; // 어떠한 그룹에 4개 이상의 이미지가 있거나, 최대 대기 시간이 지나면 병합을 시작합니다. +// if (allGroupsHaveEnoughImages) { +// break; // 모든 그룹에 4개 이상의 이미지가 있는 경우 병합을 시작 // } + // 어떠한 그룹에 대해 4개 이상의 이미지를 가진 그룹이 있는지 확인 + boolean anyGroupHasEnoughImages = groupedFiles.values().stream().anyMatch(list -> list.size() >= 4); + + if (anyGroupHasEnoughImages || System.currentTimeMillis() - startTime > MAX_WAIT_TIME) { + break; // 어떠한 그룹에 4개 이상의 이미지가 있거나, 최대 대기 시간이 지나면 병합을 시작합니다. + } + if (System.currentTimeMillis() - startTime > MAX_WAIT_TIME) { throw new IOException("이미지 업로드 대기 시간이 초과되었습니다."); } @@ -312,7 +315,7 @@ public void mergeImagesIfNeeded(int challengeNum, Lucky lucky) throws IOExceptio // UUID 생성 및 파일 이름 설정 String uuid = UUID.randomUUID().toString(); // String baseName = "merged-images/" + uuid + "_" + challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; - String baseName = "merged-images/" + "life4cut_"+ challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; + String baseName = "merged-images/" + "life4cut_" + challengeNum + "_" + lucky.getLuckyId() + "_cut_" + key + ".png"; BufferedImage mergedImage = ImageMerger.mergeImages(selectedImages); // 병합된 이미지를 S3에 업로드 @@ -502,13 +505,25 @@ public String uploadMergedImageToS3(BufferedImage mergedImage, String bucketName ObjectMetadata meta = new ObjectMetadata(); meta.setContentLength(buffer.length); meta.setContentType("image/png"); - - amazonS3Client.putObject(new PutObjectRequest(bucketName, fileObjKeyName, is, meta).withCannedAcl(CannedAccessControlList.PublicRead)); - - // 선택: amazonS3Client.getUrl(bucketName, fileObjKeyName).toString(); 또는 String.format을 사용 - return amazonS3Client.getUrl(bucketName, fileObjKeyName).toString(); - // 또는 - // return String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, fileObjKeyName); + try { + log.info("파일 업로드 시작: {}", fileObjKeyName); + amazonS3Client.putObject(new PutObjectRequest(bucketName, fileObjKeyName, is, meta).withCannedAcl(CannedAccessControlList.PublicRead)); + log.info("파일 업로드 완료: {}", fileObjKeyName); + + // 선택: amazonS3Client.getUrl(bucketName, fileObjKeyName).toString(); 또는 String.format을 사용 + return amazonS3Client.getUrl(bucketName, fileObjKeyName).toString(); + // 또는 + // return String.format("https://%s.s3.%s.amazonaws.com/%s", bucketName, region, fileObjKeyName); + } catch (AmazonServiceException e) { + log.error("Amazon 서비스 예외 발생: {}", e.getMessage(), e); + throw e; + } catch (SdkClientException e) { + log.error("SDK 클라이언트 예외 발생: {}", e.getMessage(), e); + throw e; + } catch (Exception e) { + log.error("알 수 없는 예외 발생: {}", e.getMessage(), e); + throw e; + } } // 특정 챌린지와 럭키 번호에 대한 이미지 결과를 가져오는 메서드