diff --git a/module-admin/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java b/module-admin/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java index ce8eb22c..d05471a4 100644 --- a/module-admin/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java +++ b/module-admin/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java @@ -60,7 +60,7 @@ public class DetailBoardResponse { private boolean myLikeYn; @Schema(description = "댓글 수") - private int replyCount; + private long replyCount; @Schema(description = "최종 저장 여부") private boolean saveYn; diff --git a/module-admin/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java b/module-admin/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java index c8628ca4..b2819dcc 100644 --- a/module-admin/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java +++ b/module-admin/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java @@ -2,6 +2,7 @@ import static org.example.domain.board.QBoard.board; import static org.example.domain.board_like.QBoardLike.boardLike; +import static org.example.domain.reply.QReply.reply; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.Expressions; @@ -47,7 +48,14 @@ public DetailBoardResponse getBoard(Long boardId) { boardLike.member.email.eq(SecurityUtils.getCurrentMemberEmail()) ).exists() , "myLikeYn"), - board.replyList.size().as("replyCount"), + Expressions.as( + JPAExpressions + .select(reply.count()) + .from(reply) + .where( + reply.board.eq(board), + reply.deleteYn.isFalse()) + , "replyCount"), board.saveYn, board.fixYn, board.deleteYn diff --git a/module-admin/src/main/java/org/example/domain/curriculum/controller/request/CreateCurriculumRequest.java b/module-admin/src/main/java/org/example/domain/curriculum/controller/request/CreateCurriculumRequest.java index aeb30ad2..8297dc66 100644 --- a/module-admin/src/main/java/org/example/domain/curriculum/controller/request/CreateCurriculumRequest.java +++ b/module-admin/src/main/java/org/example/domain/curriculum/controller/request/CreateCurriculumRequest.java @@ -1,7 +1,6 @@ package org.example.domain.curriculum.controller.request; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @Schema(description = "커리큘럼 생성 요청 객체") @@ -11,15 +10,12 @@ public record CreateCurriculumRequest( @Schema(description = "커리큘럼 대상 스터디 ID") Long studyId, - @NotBlank @Schema(description = "커리큘럼 제목") String title, - @NotNull @Schema(description = "커리큘럼 주차") Integer week, - @NotBlank @Schema(description = "커리큘럼 내용(에디터)") String content ) { diff --git a/module-admin/src/main/java/org/example/domain/curriculum/service/CreateCurriculumService.java b/module-admin/src/main/java/org/example/domain/curriculum/service/CreateCurriculumService.java index 6138cf68..437dc6e7 100644 --- a/module-admin/src/main/java/org/example/domain/curriculum/service/CreateCurriculumService.java +++ b/module-admin/src/main/java/org/example/domain/curriculum/service/CreateCurriculumService.java @@ -12,6 +12,7 @@ import org.example.domain.study.service.CoreStudyService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; @Service @RequiredArgsConstructor @@ -26,6 +27,11 @@ public class CreateCurriculumService { * 커리큘럼 생성 */ public void createCurriculum(CreateCurriculumRequest request) { + if (!StringUtils.hasText(request.title()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "제목 또는 내용이 비어있습니다."); + if (request.week() == null) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "주차 선택은 필수입니다."); + Study study = coreStudyService.findById(request.studyId()); if (study.getType().equals(StudyType.TEMP)) { throw new GeneralException(ErrorStatus.BAD_REQUEST, "자율 스터디는 커리큘럼을 생성할 수 없습니다."); @@ -45,6 +51,11 @@ public void createCurriculum(CreateCurriculumRequest request) { * 커리큘럼 수정 */ public void updateCurriculum(Long curriculumId, UpdateCurriculumRequest request) { + if (!StringUtils.hasText(request.title()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "제목 또는 내용이 비어있습니다."); + if (request.week() == null) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "주차 선택은 필수입니다."); + Curriculum curriculum = coreCurriculumService.findById(curriculumId); Study study = null; if (request.studyId() != null) { diff --git a/module-admin/src/main/java/org/example/domain/generation/service/CreateGenerationService.java b/module-admin/src/main/java/org/example/domain/generation/service/CreateGenerationService.java index 257903b3..53adefca 100644 --- a/module-admin/src/main/java/org/example/domain/generation/service/CreateGenerationService.java +++ b/module-admin/src/main/java/org/example/domain/generation/service/CreateGenerationService.java @@ -89,6 +89,7 @@ public void renewGeneration(RenewGenerationRequest request) { memberRepository.initBlockYN(); List regularStudyList = listStudyRepository.getOldGenerationStudyList(StudyType.REGULAR); for (Study oldStudy : regularStudyList) { + oldStudy.end(); Study newStudy = Study.builder() .profileUrl(oldStudy.getProfileUrl()) .name(oldStudy.getName()) diff --git a/module-admin/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java b/module-admin/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java index d703798f..dd712236 100644 --- a/module-admin/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java +++ b/module-admin/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java @@ -43,7 +43,7 @@ public class DetailInquiryResponse { private String content; @Schema(description = "댓글 수") - private int replyCount; + private long replyCount; @Schema(description = "공개 여부") private boolean publicYn; diff --git a/module-admin/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java b/module-admin/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java index 475f3cad..ee85cb7b 100644 --- a/module-admin/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java +++ b/module-admin/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java @@ -2,8 +2,11 @@ import static org.example.domain.inquiry.QInquiry.inquiry; +import static org.example.domain.inquiry_reply.QInquiryReply.inquiryReply; import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.example.domain.inquiry.controller.response.DetailInquiryResponse; @@ -30,7 +33,14 @@ public DetailInquiryResponse getInquiry(Long inquiryId) { inquiry.member.profileUrl, inquiry.createdTime, inquiry.viewCount, - inquiry.replyList.size().as("replyCount"), + Expressions.as( + JPAExpressions + .select(inquiryReply.count()) + .from(inquiryReply) + .where( + inquiryReply.inquiry.eq(inquiry), + inquiryReply.deleteYn.isFalse()) + , "replyCount"), inquiry.publicYn, inquiry.solvedYn )) diff --git a/module-admin/src/main/java/org/example/domain/institution/controller/request/CreateInstitutionRequest.java b/module-admin/src/main/java/org/example/domain/institution/controller/request/CreateInstitutionRequest.java index 79ec3279..dc5899de 100644 --- a/module-admin/src/main/java/org/example/domain/institution/controller/request/CreateInstitutionRequest.java +++ b/module-admin/src/main/java/org/example/domain/institution/controller/request/CreateInstitutionRequest.java @@ -2,22 +2,17 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import org.example.domain.institution.enums.InstitutionType; @Schema(description = "기관 생성 요청 객체") public record CreateInstitutionRequest( - @NotBlank @Schema(description = "기관명", requiredMode = RequiredMode.REQUIRED) String name, - @NotNull @Schema(description = "기관 유형", requiredMode = RequiredMode.REQUIRED) InstitutionType type, - @NotBlank @Schema(description = "분석 내용", requiredMode = RequiredMode.REQUIRED) String content ) { diff --git a/module-admin/src/main/java/org/example/domain/institution/service/CreateInstitutionService.java b/module-admin/src/main/java/org/example/domain/institution/service/CreateInstitutionService.java index b991c351..dd802148 100644 --- a/module-admin/src/main/java/org/example/domain/institution/service/CreateInstitutionService.java +++ b/module-admin/src/main/java/org/example/domain/institution/service/CreateInstitutionService.java @@ -11,6 +11,7 @@ import org.example.domain.workbook.repository.WorkbookRepository; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.util.StringUtils; @Service @RequiredArgsConstructor @@ -25,8 +26,13 @@ public class CreateInstitutionService { * 기관 생성 */ public void createInstitution(CreateInstitutionRequest request) { + if (!StringUtils.hasText(request.name()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이름 또는 내용이 비어있습니다."); + if (request.type() == null) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "주차 선택은 필수입니다."); + if (institutionRepository.findByName(request.name()).isPresent()) { - throw new GeneralException(ErrorStatus.BAD_REQUEST, "이미 존재하는 기관명입니다."); + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이미 존재하는 기관명입니다."); } institutionRepository.save( @@ -42,6 +48,11 @@ public void createInstitution(CreateInstitutionRequest request) { * 기관 수정 */ public void updateInstitution(Long institutionId, UpdateInstitutionRequest request) { + if (!StringUtils.hasText(request.name()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이름 또는 내용이 비어있습니다."); + if (request.type() == null) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "주차 선택은 필수입니다."); + Institution institution = coreInstitutionService.findById(institutionId); institution.update( request.name(), diff --git a/module-admin/src/main/java/org/example/domain/study/controller/request/CreateRegularStudyRequest.java b/module-admin/src/main/java/org/example/domain/study/controller/request/CreateRegularStudyRequest.java index db998484..2c8414d8 100644 --- a/module-admin/src/main/java/org/example/domain/study/controller/request/CreateRegularStudyRequest.java +++ b/module-admin/src/main/java/org/example/domain/study/controller/request/CreateRegularStudyRequest.java @@ -1,7 +1,6 @@ package org.example.domain.study.controller.request; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; @Schema(description = "정규 스터디 생성 요청 객체") public record CreateRegularStudyRequest( @@ -9,11 +8,9 @@ public record CreateRegularStudyRequest( @Schema(description = "스터디 대표 이미지 URL") String profileUrl, - @NotBlank @Schema(description = "스터디 이름") String name, - @NotBlank @Schema(description = "내용(에디터)") String content diff --git a/module-admin/src/main/java/org/example/domain/study/service/CreateStudyService.java b/module-admin/src/main/java/org/example/domain/study/service/CreateStudyService.java index 1a164a63..e2a725ee 100644 --- a/module-admin/src/main/java/org/example/domain/study/service/CreateStudyService.java +++ b/module-admin/src/main/java/org/example/domain/study/service/CreateStudyService.java @@ -36,6 +36,9 @@ public class CreateStudyService { * 정규 스터디 생성 */ public void createRegularStudy(CreateRegularStudyRequest request) { + if (!StringUtils.hasText(request.name()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이름 또는 내용이 비어있습니다."); + if (studyRepository.findByNameAndTypeIs(request.name(), StudyType.REGULAR).isPresent()) { throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "동일한 이름의 정규 스터디가 존재합니다."); } @@ -56,6 +59,9 @@ public void createRegularStudy(CreateRegularStudyRequest request) { * 스터디 수정 */ public void updateStudy(Long studyId, UpdateStudyRequest request) { + if (!StringUtils.hasText(request.name()) || !StringUtils.hasText(request.content())) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이름 또는 내용이 비어있습니다."); + Study study = coreStudyService.findById(studyId); if (study.getType().equals(StudyType.TEMP)) { throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "자율 스터디는 수정할 수 없습니다."); diff --git a/module-admin/src/main/java/org/example/domain/week/controller/response/DetailWeekResponse.java b/module-admin/src/main/java/org/example/domain/week/controller/response/DetailWeekResponse.java index d050b327..e1d18b95 100644 --- a/module-admin/src/main/java/org/example/domain/week/controller/response/DetailWeekResponse.java +++ b/module-admin/src/main/java/org/example/domain/week/controller/response/DetailWeekResponse.java @@ -1,5 +1,6 @@ package org.example.domain.week.controller.response; +import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.v3.oas.annotations.media.Schema; import java.time.LocalDateTime; import lombok.AllArgsConstructor; @@ -14,6 +15,9 @@ @Schema(description = "현재 주차 정보 응답 객체") public class DetailWeekResponse { + @JsonIgnore + private long weekId; + @Schema(description = "현재 기수") private int generation; diff --git a/module-admin/src/main/java/org/example/domain/week/repository/DetailWeekRepository.java b/module-admin/src/main/java/org/example/domain/week/repository/DetailWeekRepository.java index bd25c061..6b719ec7 100644 --- a/module-admin/src/main/java/org/example/domain/week/repository/DetailWeekRepository.java +++ b/module-admin/src/main/java/org/example/domain/week/repository/DetailWeekRepository.java @@ -21,10 +21,11 @@ public class DetailWeekRepository { /** * 현재 주차 정보 조회 */ - public DetailWeekResponse getWeek() { + public DetailWeekResponse getCurrentWeek() { return queryFactory .select(Projections.fields( DetailWeekResponse.class, + week.id.as("weekId"), Expressions.as( JPAExpressions .select( diff --git a/module-admin/src/main/java/org/example/domain/week/service/DetailWeekService.java b/module-admin/src/main/java/org/example/domain/week/service/DetailWeekService.java index d1137e5a..a267380c 100644 --- a/module-admin/src/main/java/org/example/domain/week/service/DetailWeekService.java +++ b/module-admin/src/main/java/org/example/domain/week/service/DetailWeekService.java @@ -21,7 +21,7 @@ public class DetailWeekService { * 현재 주차 정보 조회 */ public DetailWeekResponse getWeek() { - DetailWeekResponse week = detailWeekRepository.getWeek(); + DetailWeekResponse week = detailWeekRepository.getCurrentWeek(); if (week == null) { Integer generation = generationRepository.findTopByOrderByValueDesc().getValue(); throw new GeneralException(ErrorStatus.ATTENDANCE_ENDED, generation + "기 스터디 진행 기간이 아닙니다."); diff --git a/module-admin/src/main/java/org/example/domain/workbook/service/CreateWorkbookService.java b/module-admin/src/main/java/org/example/domain/workbook/service/CreateWorkbookService.java index 54cb6f22..5119e022 100644 --- a/module-admin/src/main/java/org/example/domain/workbook/service/CreateWorkbookService.java +++ b/module-admin/src/main/java/org/example/domain/workbook/service/CreateWorkbookService.java @@ -1,16 +1,20 @@ package org.example.domain.workbook.service; +import java.time.LocalDate; import lombok.RequiredArgsConstructor; import org.example.api_response.exception.GeneralException; import org.example.api_response.status.ErrorStatus; import org.example.domain.problem.Problem; import org.example.domain.problem.service.CoreProblemService; +import org.example.domain.week.controller.response.DetailWeekResponse; +import org.example.domain.week.repository.DetailWeekRepository; import org.example.domain.workbook.Workbook; import org.example.domain.workbook.controller.request.UpdateWorkbookRequest; import org.example.domain.workbook.repository.WorkbookRepository; import org.example.domain.workbook_problem.WorkbookProblem; import org.example.domain.workbook_problem.controller.request.CreateWorkbookProblemRequest; import org.example.domain.workbook_problem.repository.WorkbookProblemRepository; +import org.example.util.DateUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,6 +28,7 @@ public class CreateWorkbookService { private final WorkbookRepository workbookRepository; private final WorkbookProblemRepository workbookProblemRepository; + private final DetailWeekRepository detailWeekRepository; /** @@ -46,11 +51,20 @@ public void deleteWorkbook(Long workbookId) { */ public void createWorkbookProblem(Long workbookId, CreateWorkbookProblemRequest request) { Workbook workbook = coreWorkbookService.findById(workbookId); + DetailWeekResponse currentWeek = detailWeekRepository.getCurrentWeek(); + if (workbook.getStudy().getEndYN() || // 종료된 스터디 수정 불가 + !(workbook.getWeek().getId().equals(currentWeek.getWeekId()) // 현재 주차의 문제집이면서 + && !DateUtils.isWeekend(LocalDate.now()) // 주말이 아니면서 + && !workbook.getStudy().getEndYN() // 진행 중이면 수정 가능 + ) + ) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "스터디원에게 공개된 문제는 수정할 수 없습니다."); + Problem problem = coreProblemService.findByNumber(request.number()); if (workbookProblemRepository.findByWorkbookAndProblem(workbook, problem).isPresent()) { throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "이미 문제집에 포함된 문제입니다."); } - workbookProblemRepository.save( + workbook.getWorkbookProblemList().add( WorkbookProblem.builder() .workbook(workbook) .problem(problem) @@ -62,6 +76,16 @@ public void createWorkbookProblem(Long workbookId, CreateWorkbookProblemRequest * 문제집 문제 삭제 */ public void deleteWorkbookProblem(Long workbookId, Integer problemNumber) { - workbookProblemRepository.deleteByWorkbookIdAndProblemNumber(workbookId, problemNumber); + Workbook workbook = coreWorkbookService.findById(workbookId); + DetailWeekResponse currentWeek = detailWeekRepository.getCurrentWeek(); + if (workbook.getStudy().getEndYN() || // 종료된 스터디 삭제 불가 + !(workbook.getWeek().getId().equals(currentWeek.getWeekId()) // 현재 주차의 문제집이면서 + && !DateUtils.isWeekend(LocalDate.now()) // 주말이 아니면서 + && !workbook.getStudy().getEndYN() // 진행 중이면 삭제 가능 + ) + ) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "스터디원에게 공개된 문제는 삭제할 수 없습니다."); + + workbookProblemRepository.deleteByWorkbookAndProblemNumber(workbook, problemNumber); } } diff --git a/module-core/src/main/java/org/example/domain/workbook_problem/repository/WorkbookProblemRepository.java b/module-core/src/main/java/org/example/domain/workbook_problem/repository/WorkbookProblemRepository.java index b02dc381..4ceebe6b 100644 --- a/module-core/src/main/java/org/example/domain/workbook_problem/repository/WorkbookProblemRepository.java +++ b/module-core/src/main/java/org/example/domain/workbook_problem/repository/WorkbookProblemRepository.java @@ -10,7 +10,7 @@ public interface WorkbookProblemRepository extends JpaRepository { @Modifying - void deleteByWorkbookIdAndProblemNumber(Long workbookId, Integer number); + void deleteByWorkbookAndProblemNumber(Workbook workbook, Integer number); Optional findByWorkbookAndProblem(Workbook workbook, Problem problem); } diff --git a/module-core/src/main/java/org/example/util/DateUtils.java b/module-core/src/main/java/org/example/util/DateUtils.java index 82208700..f3599d0f 100644 --- a/module-core/src/main/java/org/example/util/DateUtils.java +++ b/module-core/src/main/java/org/example/util/DateUtils.java @@ -4,6 +4,8 @@ import static java.time.temporal.ChronoUnit.HOURS; import static java.time.temporal.ChronoUnit.MINUTES; +import java.time.DayOfWeek; +import java.time.LocalDate; import java.time.LocalDateTime; public class DateUtils { @@ -24,4 +26,8 @@ public static String getUpdatedTime(LocalDateTime updatedTime) { return dayGap + "일 전"; } + + public static boolean isWeekend(LocalDate localDate) { + return (localDate.getDayOfWeek() == DayOfWeek.SATURDAY || localDate.getDayOfWeek() == DayOfWeek.SUNDAY); + } } diff --git a/module-user/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java b/module-user/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java index 761d1e1b..010f23bc 100644 --- a/module-user/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java +++ b/module-user/src/main/java/org/example/domain/board/controller/response/DetailBoardResponse.java @@ -63,7 +63,7 @@ public class DetailBoardResponse { private boolean myLikeYn; @Schema(description = "댓글 수") - private int replyCount; + private long replyCount; @Schema(description = "최종 저장 여부") private boolean saveYn; diff --git a/module-user/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java b/module-user/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java index 9adde4ad..e731b62e 100644 --- a/module-user/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java +++ b/module-user/src/main/java/org/example/domain/board/repository/DetailBoardRepository.java @@ -2,6 +2,7 @@ import static org.example.domain.board.QBoard.board; import static org.example.domain.board_like.QBoardLike.boardLike; +import static org.example.domain.reply.QReply.reply; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.Expressions; @@ -40,7 +41,14 @@ public DetailBoardResponse getBoard(Long boardId) { board.saveYn, board.deleteYn, board.fixYn, - board.replyList.size().as("replyCount"), + Expressions.as( + JPAExpressions + .select(reply.count()) + .from(reply) + .where( + reply.board.eq(board), + reply.deleteYn.isFalse()) + , "replyCount"), board.boardLikeList.size().as("likeCount"), Expressions.as( JPAExpressions diff --git a/module-user/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java b/module-user/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java index a10dc999..86f40418 100644 --- a/module-user/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java +++ b/module-user/src/main/java/org/example/domain/inquiry/controller/response/DetailInquiryResponse.java @@ -49,7 +49,7 @@ public class DetailInquiryResponse { private boolean myInquiryYn; @Schema(description = "댓글 수") - private int replyCount; + private long replyCount; @Schema(description = "공개 여부") private boolean publicYn; diff --git a/module-user/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java b/module-user/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java index 02d05d51..3f7c7c0a 100644 --- a/module-user/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java +++ b/module-user/src/main/java/org/example/domain/inquiry/repository/DetailInquiryRepository.java @@ -2,8 +2,11 @@ import static org.example.domain.inquiry.QInquiry.inquiry; +import static org.example.domain.inquiry_reply.QInquiryReply.inquiryReply; import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.example.domain.inquiry.controller.response.DetailInquiryResponse; @@ -33,7 +36,14 @@ public DetailInquiryResponse getInquiry(Long inquiryId) { inquiry.createdTime, inquiry.viewCount, inquiry.member.email.eq(SecurityUtils.getCurrentMemberEmail()).as("myInquiryYn"), - inquiry.replyList.size().as("replyCount"), + Expressions.as( + JPAExpressions + .select(inquiryReply.count()) + .from(inquiryReply) + .where( + inquiryReply.inquiry.eq(inquiry), + inquiryReply.deleteYn.isFalse()) + , "replyCount"), inquiry.publicYn, inquiry.solvedYn )) diff --git a/module-user/src/main/java/org/example/domain/inquiry/service/CreateInquiryService.java b/module-user/src/main/java/org/example/domain/inquiry/service/CreateInquiryService.java index 9290979c..8d4bfc7a 100644 --- a/module-user/src/main/java/org/example/domain/inquiry/service/CreateInquiryService.java +++ b/module-user/src/main/java/org/example/domain/inquiry/service/CreateInquiryService.java @@ -65,6 +65,8 @@ public void updateInquiry(long inquiryId, UpdateInquiryRequest request) { Inquiry inquiry = coreInquiryService.findById(inquiryId); if (!inquiry.getMember().equals(coreMemberService.findByEmail(SecurityUtils.getCurrentMemberEmail()))) throw new GeneralException(ErrorStatus.UNAUTHORIZED, "자신이 남긴 문의 이외에는 수정할 수 없습니다."); + if (inquiry.getSolvedYn()) + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "답변이 등록된 문의는 수정할 수 없습니다."); inquiry.updateInquiry( request.category(), @@ -93,7 +95,7 @@ public void deleteInquiry(long inquiryId) { if (!inquiry.getMember().equals(coreMemberService.findByEmail(SecurityUtils.getCurrentMemberEmail()))) throw new GeneralException(ErrorStatus.BAD_REQUEST, "자신이 남긴 문의 이외에는 삭제할 수 없습니다."); if (inquiry.getSolvedYn()) - throw new GeneralException(ErrorStatus.BAD_REQUEST, "답변이 등록된 문의는 삭제할 수 없습니다."); + throw new GeneralException(ErrorStatus.NOTICE_BAD_REQUEST, "답변이 등록된 문의는 삭제할 수 없습니다."); inquiryRepository.deleteById(inquiryId); } diff --git a/module-user/src/main/java/org/example/domain/workbook/controller/WorkbookController.java b/module-user/src/main/java/org/example/domain/workbook/controller/WorkbookController.java index 9fe30798..5eb06598 100644 --- a/module-user/src/main/java/org/example/domain/workbook/controller/WorkbookController.java +++ b/module-user/src/main/java/org/example/domain/workbook/controller/WorkbookController.java @@ -20,6 +20,13 @@ public class WorkbookController { private final WorkbookService workbookService; + @GetMapping("/auto") + @Operation(summary = "정규 스터디 문제집 생성(Scheduler 오류 시 실행)") + public ApiResponse createAutoWorkbook() { + workbookService.createAutoWorkbook(); + return ApiResponse.onCreate(); + } + @GetMapping("/{workbook-id}") @LimitRegularStudyMember(page = true) @Operation(summary = "문제집 상세 조회") diff --git a/module-user/src/main/java/org/example/domain/workbook/service/ListWorkbookService.java b/module-user/src/main/java/org/example/domain/workbook/service/ListWorkbookService.java index 55f8025b..1ff763d0 100644 --- a/module-user/src/main/java/org/example/domain/workbook/service/ListWorkbookService.java +++ b/module-user/src/main/java/org/example/domain/workbook/service/ListWorkbookService.java @@ -1,9 +1,14 @@ package org.example.domain.workbook.service; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; +import java.util.Optional; import lombok.RequiredArgsConstructor; import org.example.api_response.exception.GeneralException; import org.example.api_response.status.ErrorStatus; +import org.example.domain.week.Week; +import org.example.domain.week.repository.DetailWeekRepository; import org.example.domain.workbook.controller.response.ListWorkbookDto; import org.example.domain.workbook.controller.response.ListWorkbookResponse; import org.example.domain.member.Member; @@ -18,6 +23,7 @@ import org.example.domain.workbook.repository.ListWorkbookRepository; import org.example.domain.workbook_problem.controller.response.ListWorkbookProblemDto; import org.example.domain.workbook_problem.repository.ListWorkbookProblemRepository; +import org.example.util.DateUtils; import org.example.util.SecurityUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -31,6 +37,7 @@ public class ListWorkbookService { private final CoreStudyService coreStudyService; private final ListWorkbookRepository listWorkbookRepository; private final ListWorkbookProblemRepository listWorkbookProblemRepository; + private final DetailWeekRepository detailWeekRepository; private final StudyMemberRepository studyMemberRepository; /** @@ -43,13 +50,27 @@ public ListWorkbookResponse getWorkbookList(Long studyId) { } Member member = coreMemberService.findByEmail(SecurityUtils.getCurrentMemberEmail()); if (studyMemberRepository.findByStudyAndMemberAndStatus(study, member, StudyMemberStatus.PASS).isEmpty() - && member.getRole().equals(Role.ROLE_USER)) { + && member.getRole().equals(Role.ROLE_USER)) { throw new GeneralException(ErrorStatus.NOTICE_UNAUTHORIZED, "스터디원만 열람할 수 있습니다."); } + if (DateUtils.isWeekend(LocalDate.now())) { + return ListWorkbookResponse.builder() + .workbookList(new ArrayList<>()) + .build(); + } + List workbookList = listWorkbookRepository.getWorkbookList(study); + Optional optionalWeek = detailWeekRepository.getCurrentWeek(); for (ListWorkbookDto workbook : workbookList) { + // 스터디 진행 중인 경우, 현재 주차 모의테스트 문제는 주말이 아니면 비공개 + if (optionalWeek.isPresent() && optionalWeek.get().getValue().equals(workbook.getWeek()) + && !study.getEndYN() + && !DateUtils.isWeekend(LocalDate.now())) + continue; + workbook.getProblemList().addAll(listWorkbookProblemRepository.getWorkbookProblemList(workbook.getWorkbookId())); + // enum -> 티어 이미지 변환 for (ListWorkbookProblemDto problem : workbook.getProblemList()) { problem.setLevelUrl(Level.valueOf(problem.getLevelUrl())); diff --git a/module-user/src/main/java/org/example/domain/workbook/service/WorkbookService.java b/module-user/src/main/java/org/example/domain/workbook/service/WorkbookService.java index 05eea1fb..b5899b1f 100644 --- a/module-user/src/main/java/org/example/domain/workbook/service/WorkbookService.java +++ b/module-user/src/main/java/org/example/domain/workbook/service/WorkbookService.java @@ -9,9 +9,17 @@ @RequiredArgsConstructor public class WorkbookService { + private final CreateWorkbookService createWorkbookService; private final ListWorkbookService listWorkbookService; private final DetailWorkbookService detailWorkbookService; + /** + * 정규 스터디 모의테스트 생성 + */ + public void createAutoWorkbook() { + createWorkbookService.createAutoWorkbook(); + } + /** * 정규 스터디 모의테스트 조회 */ diff --git a/module-user/src/main/java/org/example/schedule/SchedulerConfig.java b/module-user/src/main/java/org/example/schedule/SchedulerConfig.java index 1957878f..a67e7652 100644 --- a/module-user/src/main/java/org/example/schedule/SchedulerConfig.java +++ b/module-user/src/main/java/org/example/schedule/SchedulerConfig.java @@ -29,9 +29,9 @@ public void createProblem() { } /** - * 매주 금요일 00:00 정규 스터디 문제집 생성 + * 매주 목요일 00:00 정규 스터디 문제집 생성 */ - @Scheduled(cron = "0 0 0 * * FRI") + @Scheduled(cron = "0 0 0 * * THU") public void createAutoWorkbook() { log.info("=========문제집 생성 스케쥴러 실행========="); createWorkbookService.createAutoWorkbook();