From 1154e88096239b891c0300723881d0d3b4ea3382 Mon Sep 17 00:00:00 2001 From: Kijun Kwon Date: Tue, 13 Aug 2024 01:19:39 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[SAMBAD-242]=20=EC=A7=88=EB=AC=B8=20?= =?UTF-8?q?=EB=8B=B5=EB=B3=80=20=ED=99=9C=EC=84=B1=ED=99=94=20=EB=B0=8F=20?= =?UTF-8?q?=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94=20=ED=94=8C=EB=A1=9C?= =?UTF-8?q?=EC=9A=B0=20=EC=9D=B4=EC=8A=88=20=ED=94=BD=EC=8A=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ObjectStorageFileUploader.java | 10 ++++++---- .../MeetingAnswerQueryRepository.java | 16 ++++++++++------ .../request/MeetingQuestionCommentRequest.java | 2 +- .../member/application/MeetingMemberService.java | 10 +++++++++- .../meeting/question/domain/MeetingQuestion.java | 6 +++++- .../MeetingQuestionQueryRepository.java | 16 +++------------- src/main/resources/application.yml | 2 +- 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/src/main/java/org/depromeet/sambad/moring/file/infrastructure/ObjectStorageFileUploader.java b/src/main/java/org/depromeet/sambad/moring/file/infrastructure/ObjectStorageFileUploader.java index 479174ae..3cf8b675 100644 --- a/src/main/java/org/depromeet/sambad/moring/file/infrastructure/ObjectStorageFileUploader.java +++ b/src/main/java/org/depromeet/sambad/moring/file/infrastructure/ObjectStorageFileUploader.java @@ -75,10 +75,9 @@ public String upload(String fileUrl) throws ObjectStorageServerException { try { String filePath = generateUploadPath(fileUrl); HttpURLConnection conn = getHttpURLConnection(fileUrl); - String contentType = conn.getHeaderField(CONTENT_TYPE); try (InputStream in = conn.getInputStream()) { - amazonS3.putObject(bucketName, filePath, in, setObjectMetaData(in, contentType)); + amazonS3.putObject(bucketName, filePath, in, setObjectMetaData(conn)); } return filePath; @@ -120,10 +119,13 @@ private HttpURLConnection getHttpURLConnection(String fileUrl) throws IOExceptio return conn; } - private ObjectMetadata setObjectMetaData(InputStream in, String contentType) throws IOException { + private ObjectMetadata setObjectMetaData(HttpURLConnection conn) throws IOException { ObjectMetadata objectMetadata = new ObjectMetadata(); - objectMetadata.setContentLength(in.available()); + String contentType = conn.getHeaderField(CONTENT_TYPE); + long contentLength = Long.parseLong(conn.getHeaderField(CONTENT_LENGTH)); + + objectMetadata.setContentLength(contentLength); objectMetadata.setContentType(contentType); return objectMetadata; } diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/answer/infrastructure/MeetingAnswerQueryRepository.java b/src/main/java/org/depromeet/sambad/moring/meeting/answer/infrastructure/MeetingAnswerQueryRepository.java index 7df28e63..fbe37493 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/answer/infrastructure/MeetingAnswerQueryRepository.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/answer/infrastructure/MeetingAnswerQueryRepository.java @@ -30,14 +30,18 @@ public class MeetingAnswerQueryRepository { private final JPAQueryFactory queryFactory; public boolean isAllAnsweredByMeetingIdAndMeetingQuestionId(Long meetingId, Long meetingQuestionId) { - return queryFactory.select(meetingAnswer.count()) + Long answeredMeetingMemberCount = queryFactory.select(meetingAnswer.meetingMember.countDistinct()) .from(meetingAnswer) .where(meetingAnswer.meetingQuestion.id.eq(meetingQuestionId)) - .fetchOne() - .equals(queryFactory.select(meetingMember.count()) - .from(meetingMember) - .where(meetingMember.meeting.id.eq(meetingId)) - .fetchOne()); + .groupBy(meetingAnswer.meetingQuestion.id) + .fetchOne(); + + Long allMemberCount = queryFactory.select(meetingMember.count()) + .from(meetingMember) + .where(meetingMember.meeting.id.eq(meetingId)) + .fetchOne(); + + return Objects.equals(answeredMeetingMemberCount, allMemberCount); } // TODO: 가장 많이 선택된 답변이 여러개일 수 있으나, 현재 로직은 하나만 반환. 추후 기획에 따라 수정 필요. diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/comment/presentation/comment/request/MeetingQuestionCommentRequest.java b/src/main/java/org/depromeet/sambad/moring/meeting/comment/presentation/comment/request/MeetingQuestionCommentRequest.java index cbc19e9d..014011b0 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/comment/presentation/comment/request/MeetingQuestionCommentRequest.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/comment/presentation/comment/request/MeetingQuestionCommentRequest.java @@ -12,7 +12,7 @@ public record MeetingQuestionCommentRequest( @Schema(description = "릴레이 질문 코멘트 내용", example = "코멘트 예시") @NotBlank - @Size(max = 10) + @Size(max = 20) String content ) { } diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/member/application/MeetingMemberService.java b/src/main/java/org/depromeet/sambad/moring/meeting/member/application/MeetingMemberService.java index a07529ce..034cacf4 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/member/application/MeetingMemberService.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/member/application/MeetingMemberService.java @@ -3,6 +3,7 @@ import java.time.LocalDateTime; import java.util.List; +import org.depromeet.sambad.moring.event.application.EventService; import org.depromeet.sambad.moring.meeting.meeting.application.MeetingRepository; import org.depromeet.sambad.moring.meeting.meeting.domain.Meeting; import org.depromeet.sambad.moring.meeting.meeting.domain.MeetingCode; @@ -27,6 +28,9 @@ import lombok.RequiredArgsConstructor; +import static org.depromeet.sambad.moring.event.domain.EventType.QUESTION_REGISTERED; +import static org.depromeet.sambad.moring.event.domain.EventType.TARGET_MEMBER; + @RequiredArgsConstructor @Service @Transactional(readOnly = true) @@ -40,6 +44,7 @@ public class MeetingMemberService { private final HobbyRepository hobbyRepository; private final MeetingQuestionRepository meetingQuestionRepository; private final MeetingMemberHobbyRepository meetingMemberHobbyRepository; + private final EventService eventService; public MeetingMemberListResponse getMeetingMembers(Long userId, Long meetingId) { meetingMemberValidator.validateUserIsMemberOfMeeting(userId, meetingId); @@ -92,11 +97,14 @@ public MeetingMemberPersistResponse registerMeetingMember( } private void createMeetingQuestionIfFirstMeetingMember(Meeting meeting, MeetingMember meetingMember) { - if (meetingMemberRepository.isCountOfMembersIsOne(meeting.getId())) { + Long meetingId = meeting.getId(); + + if (meetingMemberRepository.isCountOfMembersIsOne(meetingId)) { MeetingQuestion activeMeetingQuestion = MeetingQuestion.createActiveMeetingQuestion( meeting, meetingMember, null, LocalDateTime.now()); meetingQuestionRepository.save(activeMeetingQuestion); + eventService.publish(meetingMember.getUser().getId(), meetingId, TARGET_MEMBER); } } diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java b/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java index aee81c35..0949d91c 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java @@ -117,7 +117,11 @@ public void updateStatusToActive(LocalDateTime now) { } public int getResponseCount() { - return this.memberAnswers.size(); + return this.memberAnswers.stream() + .map(MeetingAnswer::getMeetingMember) + .map(MeetingMember::getId) + .distinct() + .toList().size(); } public String getQuestionImageUrl() { diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java b/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java index 30873f3b..a6800141 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java @@ -86,7 +86,7 @@ public MostInactiveMeetingQuestionListResponse findMostInactiveList(Long meeting .where( meetingQuestion.meeting.id.eq(meetingId), meetingQuestion.question.isNotNull(), - inactiveCond() + meetingQuestion.meetingQuestionStatus.eq(INACTIVE) ) .orderBy(orderDescByMeetingAnswerCount(), meetingQuestion.startTime.desc()) .limit(2) @@ -113,7 +113,7 @@ public FullInactiveMeetingQuestionListResponse findFullInactiveList(Long meeting .where( meetingQuestion.meeting.id.eq(meetingId), meetingQuestion.question.isNotNull(), - inactiveCond() + meetingQuestion.meetingQuestionStatus.eq(INACTIVE) ) .orderBy(orderDescByMeetingAnswerCount(), meetingQuestion.startTime.desc()) .offset(pageable.getOffset()) @@ -164,7 +164,7 @@ private BooleanExpression registeredCond() { LocalDateTime now = LocalDateTime.now(); return meetingQuestion.startTime.loe(now) .and(meetingQuestion.startTime.goe(now.minusHours(RESPONSE_TIME_LIMIT_HOURS))) - .and(isAnsweredByAllCond().not()); + .and(meetingQuestion.meetingQuestionStatus.eq(ACTIVE)); } private BooleanExpression activeCond() { @@ -172,16 +172,6 @@ private BooleanExpression activeCond() { .and(meetingQuestion.question.isNotNull()); } - private BooleanExpression inactiveCond() { - LocalDateTime now = LocalDateTime.now(); - return meetingQuestion.startTime.lt(now.minusHours(RESPONSE_TIME_LIMIT_HOURS)) - .or(isAnsweredByAllCond()); - } - - private BooleanExpression isAnsweredByAllCond() { - return meetingQuestion.memberAnswers.size().eq(meetingQuestion.meeting.meetingMembers.size()); - } - public List findStatistics(Long meetingQuestionId) { // Get total count for the percentage calculation Optional optionalTotalCount = Optional.ofNullable(queryFactory diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 08169652..75f98c77 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -2,7 +2,7 @@ spring: application: name: moring-api datasource: - url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:moring}?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true + url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:moring}?useSSL=false&allowPublicKeyRetrieval=true username: ${DB_USERNAME:root} password: ${DB_PASSWORD:root} driver-class-name: com.mysql.cj.jdbc.Driver From 71829f765e40a10de659b3f478229e64fc8b8818 Mon Sep 17 00:00:00 2001 From: Kijun Kwon Date: Tue, 13 Aug 2024 01:22:52 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[SAMBAD-242]=20=ED=8F=AC=EB=A7=B7=ED=8C=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../moring/meeting/question/domain/MeetingQuestion.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java b/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java index 0949d91c..92eb3266 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/question/domain/MeetingQuestion.java @@ -118,10 +118,10 @@ public void updateStatusToActive(LocalDateTime now) { public int getResponseCount() { return this.memberAnswers.stream() - .map(MeetingAnswer::getMeetingMember) - .map(MeetingMember::getId) - .distinct() - .toList().size(); + .map(MeetingAnswer::getMeetingMember) + .map(MeetingMember::getId) + .distinct() + .toList().size(); } public String getQuestionImageUrl() { From 8e4fbc8b26d972538e021a11803dae1d10a99adc Mon Sep 17 00:00:00 2001 From: Kijun Kwon Date: Tue, 13 Aug 2024 22:58:21 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[SAMBAD-242]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EC=82=AC=ED=95=AD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infrastructure/MeetingQuestionQueryRepository.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java b/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java index a6800141..c5d24ebd 100644 --- a/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java +++ b/src/main/java/org/depromeet/sambad/moring/meeting/question/infrastructure/MeetingQuestionQueryRepository.java @@ -86,7 +86,7 @@ public MostInactiveMeetingQuestionListResponse findMostInactiveList(Long meeting .where( meetingQuestion.meeting.id.eq(meetingId), meetingQuestion.question.isNotNull(), - meetingQuestion.meetingQuestionStatus.eq(INACTIVE) + inactiveCond() ) .orderBy(orderDescByMeetingAnswerCount(), meetingQuestion.startTime.desc()) .limit(2) @@ -113,7 +113,7 @@ public FullInactiveMeetingQuestionListResponse findFullInactiveList(Long meeting .where( meetingQuestion.meeting.id.eq(meetingId), meetingQuestion.question.isNotNull(), - meetingQuestion.meetingQuestionStatus.eq(INACTIVE) + inactiveCond() ) .orderBy(orderDescByMeetingAnswerCount(), meetingQuestion.startTime.desc()) .offset(pageable.getOffset()) @@ -172,6 +172,12 @@ private BooleanExpression activeCond() { .and(meetingQuestion.question.isNotNull()); } + private BooleanExpression inactiveCond() { + LocalDateTime now = LocalDateTime.now(); + return meetingQuestion.startTime.lt(now.minusHours(RESPONSE_TIME_LIMIT_HOURS)) + .or(meetingQuestion.meetingQuestionStatus.eq(INACTIVE)); + } + public List findStatistics(Long meetingQuestionId) { // Get total count for the percentage calculation Optional optionalTotalCount = Optional.ofNullable(queryFactory