diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/member/domain/Member.java b/WableServer/src/main/java/com/wable/www/WableServer/api/member/domain/Member.java index deefa5f..99887e0 100644 --- a/WableServer/src/main/java/com/wable/www/WableServer/api/member/domain/Member.java +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/member/domain/Member.java @@ -10,6 +10,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -104,6 +105,12 @@ public class Member extends BaseTimeEntity { @Column(name = "member_community") private String memberCommunity; + @Column(name = "member_quiz_date") + private LocalDate memberQuizDate; + + @Column(name = "member_quiz_count", columnDefinition = "INTEGER DEFAULT 0") + private int memberQuizCount; + @Builder private Member(String nickname, SocialPlatform socialPlatform, String socialId, String profileUrl, String memberEmail, String socialNickname) { this.nickname = nickname; @@ -120,6 +127,7 @@ private Member(String nickname, SocialPlatform socialPlatform, String socialId, this.memberExp = 0; this.memberBanCount = 0; this.memberCommunity = null; + this.memberQuizCount = 0; } public void decreaseGhost() { @@ -180,4 +188,14 @@ public void softDelete() { public void updateMemberCommunity(String memberCommunity) { this.memberCommunity = memberCommunity; } + + public void increaseExpQuizRight() { this.memberExp += 15.0;} + + public void increaseExpQuizWrong() { this.memberExp += 8.0;} + + public void increaseQuizCount() { this.memberQuizCount += 1;} + + public void updateQuizCount() { this.memberQuizCount = 1;} + + public void updateMemberQuizDate(LocalDate localDate) { this.memberQuizDate = localDate;} } diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/controller/QuizController.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/controller/QuizController.java index ec50312..f7c6dbe 100644 --- a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/controller/QuizController.java +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/controller/QuizController.java @@ -1,16 +1,18 @@ package com.wable.www.WableServer.api.quiz.controller; +import com.wable.www.WableServer.api.quiz.dto.request.QuizGradeRequestDto; import com.wable.www.WableServer.api.quiz.dto.response.QuizGetResponseDto; +import com.wable.www.WableServer.api.quiz.dto.response.QuizGradeResponseDto; +import com.wable.www.WableServer.api.quiz.service.QuizCommandService; import com.wable.www.WableServer.api.quiz.service.QuizQueryService; import com.wable.www.WableServer.common.response.ApiResponse; +import com.wable.www.WableServer.common.util.MemberUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.security.Principal; @@ -23,10 +25,17 @@ @Tag(name="퀴즈 관련",description = "Quiz Api Document") public class QuizController { private final QuizQueryService quizQueryService; + private final QuizCommandService quizCommandService; @GetMapping("v1/quiz") @Operation(summary = "퀴즈 조회 API 입니다.",description = "Quiz Get") public ResponseEntity> getQuiz(Principal principal) { return ApiResponse.success(GET_QUIZ_SUCCESS, quizQueryService.getQuiz()); } + + @PatchMapping("v1/quiz/grade") + @Operation(summary = "퀴즈 채점 API 입니다.",description = "Quiz Grade") + public ResponseEntity> gradeQuiz(Principal principal, @RequestBody QuizGradeRequestDto quizGradeRequestDto) { + return ApiResponse.success(GRADE_QUIZ_SUCCESS, quizCommandService.gradeQuiz(MemberUtil.getMemberId(principal), quizGradeRequestDto)); + } } diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/domain/QuizTime.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/domain/QuizTime.java new file mode 100644 index 0000000..c64dda1 --- /dev/null +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/domain/QuizTime.java @@ -0,0 +1,30 @@ +package com.wable.www.WableServer.api.quiz.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import static lombok.AccessLevel.PROTECTED; + +@Entity +@Getter +@NoArgsConstructor(access = PROTECTED) +public class QuizTime { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "quiz_id") + private Long quizId; + + @Column(name = "quiz_time") + private int quizTime; + + @Builder + public QuizTime(Long quizId, int quizTime) { + this.quizId = quizId; + this.quizTime = quizTime; + } +} diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/request/QuizGradeRequestDto.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/request/QuizGradeRequestDto.java new file mode 100644 index 0000000..3fc504b --- /dev/null +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/request/QuizGradeRequestDto.java @@ -0,0 +1,8 @@ +package com.wable.www.WableServer.api.quiz.dto.request; + +public record QuizGradeRequestDto( + Long quizId, + Boolean userAnswer, + int quizTime +) { +} diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/response/QuizGradeResponseDto.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/response/QuizGradeResponseDto.java new file mode 100644 index 0000000..802d7f9 --- /dev/null +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/dto/response/QuizGradeResponseDto.java @@ -0,0 +1,15 @@ +package com.wable.www.WableServer.api.quiz.dto.response; + +public record QuizGradeResponseDto( + Boolean quizResult, + int userPercent, + int continueNumber +) { + public static QuizGradeResponseDto of(Boolean quizResult, int userPercent, int continueNumber) { + return new QuizGradeResponseDto( + quizResult, + userPercent, + continueNumber + ); + } +} diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/repository/QuizTimeRepository.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/repository/QuizTimeRepository.java new file mode 100644 index 0000000..8ae92c3 --- /dev/null +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/repository/QuizTimeRepository.java @@ -0,0 +1,10 @@ +package com.wable.www.WableServer.api.quiz.repository; + +import com.wable.www.WableServer.api.quiz.domain.QuizTime; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface QuizTimeRepository extends JpaRepository { + List findAllByQuizIdOrderByQuizTimeAsc(Long quizId); +} diff --git a/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/service/QuizCommandService.java b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/service/QuizCommandService.java new file mode 100644 index 0000000..2f7d578 --- /dev/null +++ b/WableServer/src/main/java/com/wable/www/WableServer/api/quiz/service/QuizCommandService.java @@ -0,0 +1,76 @@ +package com.wable.www.WableServer.api.quiz.service; + +import com.wable.www.WableServer.api.member.domain.Member; +import com.wable.www.WableServer.api.member.repository.MemberRepository; +import com.wable.www.WableServer.api.quiz.domain.Quiz; +import com.wable.www.WableServer.api.quiz.domain.QuizTime; +import com.wable.www.WableServer.api.quiz.dto.request.QuizGradeRequestDto; +import com.wable.www.WableServer.api.quiz.dto.response.QuizGradeResponseDto; +import com.wable.www.WableServer.api.quiz.repository.QuizRepository; +import com.wable.www.WableServer.api.quiz.repository.QuizTimeRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.time.Period; +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional +public class QuizCommandService { + private final QuizRepository quizRepository; + private final QuizTimeRepository quizTimeRepository; + private final MemberRepository memberRepository; + + public QuizGradeResponseDto gradeQuiz(Long memberId, QuizGradeRequestDto quizGradeRequestDto) { + Member member = memberRepository.findMemberByIdOrThrow(memberId); + LocalDate today = LocalDate.now(); + LocalDate memberQuizDate = member.getMemberQuizDate(); + int memberQuizCount = member.getMemberQuizCount(); + Quiz quiz = quizRepository.findQuizById(quizGradeRequestDto.quizId()); + Boolean quizResult = quiz.getQuizAnswer()==quizGradeRequestDto.userAnswer(); + + QuizTime newQuizTime = quizTimeRepository.save(QuizTime.builder() + .quizId(quizGradeRequestDto.quizId()) + .quizTime(quizGradeRequestDto.quizTime()) + .build()); + + List quizTimes = quizTimeRepository.findAllByQuizIdOrderByQuizTimeAsc(quizGradeRequestDto.quizId()); + int rank = 1; + for(int i = 0; i < quizTimes.size(); i++) { + if(quizTimes.get(i).getId().equals(newQuizTime.getId())){ + rank = i + 1; + break; + } + } + double percent = ((double) rank / quizTimes.size()) * 100; + int memberPercent = (int) Math.floor(percent); + + if(quizResult){ + member.increaseExpQuizRight(); + }else { + member.increaseExpQuizWrong(); + } + + if(compareDate(memberQuizDate,today)){ + member.updateMemberQuizDate(today); + member.increaseQuizCount(); + return QuizGradeResponseDto.of(quizResult,memberPercent,memberQuizCount + 1); + }else{ + member.updateMemberQuizDate(today); + member.updateQuizCount(); + return QuizGradeResponseDto.of(quizResult,memberPercent,1); + } + + + } + public boolean compareDate(LocalDate date1, LocalDate date2) { + if(date1==null||date2==null) { + return false; + } + int diff = Math.abs(Period.between(date1,date2).getDays()); + return diff == 1; + } +} diff --git a/WableServer/src/main/java/com/wable/www/WableServer/common/response/SuccessStatus.java b/WableServer/src/main/java/com/wable/www/WableServer/common/response/SuccessStatus.java index c8b3e8e..8ae514a 100644 --- a/WableServer/src/main/java/com/wable/www/WableServer/common/response/SuccessStatus.java +++ b/WableServer/src/main/java/com/wable/www/WableServer/common/response/SuccessStatus.java @@ -93,7 +93,8 @@ public enum SuccessStatus { /** * Quiz */ - GET_QUIZ_SUCCESS(HttpStatus.OK, "퀴즈 조회 성공") + GET_QUIZ_SUCCESS(HttpStatus.OK, "퀴즈 조회 성공"), + GRADE_QUIZ_SUCCESS(HttpStatus.OK, "퀴즈 채점 성공") ; private final HttpStatus httpStatus;