Skip to content

Commit fbe4fec

Browse files
authored
Merge pull request #14 from Team-HoEunLee/feat/13-add-user-area-solved-api
feat(#13) :: 분야별 푼문제 카운트 API
2 parents c122bdc + 267ef22 commit fbe4fec

File tree

7 files changed

+171
-10
lines changed

7 files changed

+171
-10
lines changed

src/main/java/JavaProject/Dayoung/domain/area/domain/Area.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,4 @@ public class Area {
1717

1818
@Column(columnDefinition = "varchar(15)")
1919
private String areaName;
20-
2120
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package JavaProject.Dayoung.domain.quiz.domain;
2+
3+
import JavaProject.Dayoung.domain.area.domain.Area;
4+
import JavaProject.Dayoung.domain.user.domain.User;
5+
import lombok.*;
6+
7+
import javax.persistence.*;
8+
9+
/*
10+
사용자별 푼 문제의 분야를 통계, 관리하는 엔티티
11+
12+
각 사용자가 특정 분야에서 해결한 문제의 수를 추적합니다.
13+
User와 Area 엔티티와의 다대일 관계를 통해 통계 정보를 저장합니다.
14+
*/
15+
@Entity
16+
@Getter
17+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
18+
@AllArgsConstructor
19+
@Builder
20+
public class UserAreaSolved {
21+
@Id
22+
@GeneratedValue(strategy = GenerationType.IDENTITY)
23+
private Long id;
24+
25+
@ManyToOne(fetch = FetchType.LAZY)
26+
@JoinColumn(name = "user_id", nullable = false)
27+
private User user;
28+
29+
@ManyToOne(fetch = FetchType.LAZY)
30+
@JoinColumn(name = "area_id", nullable = false)
31+
private Area area;
32+
33+
@Column(nullable = false)
34+
private Long solvedCount;
35+
36+
// 카운트를 증가시키는 메서드
37+
public void incrementSolvedCount() {
38+
this.solvedCount++;
39+
}
40+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package JavaProject.Dayoung.domain.quiz.presentation;
2+
3+
import JavaProject.Dayoung.domain.quiz.presentation.dto.response.UserAreaSolvedResponse;
4+
import JavaProject.Dayoung.domain.quiz.service.UserAreaSolvedService;
5+
import io.swagger.v3.oas.annotations.Operation;
6+
import io.swagger.v3.oas.annotations.tags.Tag;
7+
import lombok.RequiredArgsConstructor;
8+
import org.springframework.web.bind.annotation.GetMapping;
9+
import org.springframework.web.bind.annotation.PathVariable;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
import java.util.List;
14+
15+
@RestController
16+
@RequiredArgsConstructor
17+
@Tag(name = "사용자 분야별 문제 풀이 통계", description = "사용자가 푼 문제의 분야별 통계를 조회")
18+
@RequestMapping("/user/area-solved")
19+
public class UserAreaSolvedController {
20+
21+
private final UserAreaSolvedService userAreaSolvedService;
22+
23+
@GetMapping("/{user-id}")
24+
@Operation(summary = "사용자 분야별 문제 풀이 통계 조회", description = "특정 사용자의 분야별 문제 풀이 통계를 조회합니다.")
25+
public List<UserAreaSolvedResponse> getUserAreaSolvedStats(@PathVariable("user-id") Long userId) {
26+
return userAreaSolvedService.getUserAreaSolvedStats(userId);
27+
}
28+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package JavaProject.Dayoung.domain.quiz.presentation.dto.response;
2+
3+
import JavaProject.Dayoung.domain.area.domain.Area;
4+
import lombok.AllArgsConstructor;
5+
import lombok.Builder;
6+
import lombok.Getter;
7+
8+
import javax.validation.constraints.NotNull;
9+
import javax.validation.constraints.PositiveOrZero;
10+
11+
@Getter
12+
@Builder
13+
@AllArgsConstructor
14+
public class UserAreaSolvedResponse {
15+
16+
@NotNull(message = "영역은 null일 수 없습니다")
17+
private Area area;
18+
19+
@NotNull(message = "해결한 문제 수는 null일 수 없습니다")
20+
@PositiveOrZero(message = "해결한 문제 수는 0 이상이어야 합니다")
21+
private Long solvedCount;
22+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package JavaProject.Dayoung.domain.quiz.repository;
2+
3+
import JavaProject.Dayoung.domain.area.domain.Area;
4+
import JavaProject.Dayoung.domain.quiz.domain.UserAreaSolved;
5+
import JavaProject.Dayoung.domain.user.domain.User;
6+
import org.springframework.data.jpa.repository.JpaRepository;
7+
import org.springframework.data.jpa.repository.Query;
8+
import org.springframework.data.repository.query.Param;
9+
import org.springframework.stereotype.Repository;
10+
11+
import java.util.List;
12+
import java.util.Optional;
13+
14+
@Repository
15+
public interface UserAreaSolvedRepository extends JpaRepository<UserAreaSolved, Long> {
16+
Optional<UserAreaSolved> findByUserAndArea(User user, Area area);
17+
18+
@Query("SELECT uas FROM UserAreaSolved uas WHERE uas.user.id = :userId")
19+
List<UserAreaSolved> findAllByUserId(@Param("userId") Long userId);
20+
}

src/main/java/JavaProject/Dayoung/domain/quiz/service/SolveQuizService.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,35 @@
2121
@Transactional
2222
@RequiredArgsConstructor
2323
public class SolveQuizService {
24-
2524
private final UserFacade userFacade;
2625
private final TemplateConfig templateConfig;
2726
private final QuizRepository quizRepository;
2827
private final SolvedQuizRepository solvedQuizRepository;
28+
private final UserAreaSolvedService userAreaSolvedService;
2929

3030
public Map<String, String> execute(Long quizId, SolveQuizRequest request) {
31-
3231
Quiz quiz = quizRepository.findQuizById(quizId);
3332

3433
ChatGPTRequest gptRequest = templateConfig.promptMapping(quiz.getQuestion(), request);
3534
ResponseEntity<ChatGPTResponse> gptResponse = templateConfig.responseMapping(gptRequest);
3635

3736
String responseContent = gptResponse.getBody().getChoices().get(0).getMessage().getContent();
38-
3937
String correctRate = templateConfig.correctRateMatcher(responseContent);
4038
String feedback = templateConfig.feedbackMatcher(responseContent);
4139

40+
SolvedQuiz solvedQuiz = solvedQuizRepository.save(SolvedQuiz.builder()
41+
.user(userFacade.getCurrentUser())
42+
.quiz(quiz)
43+
.receivedScore(Long.valueOf(correctRate))
44+
.build());
45+
46+
// 분야별 통계 업데이트
47+
userAreaSolvedService.updateUserAreaSolved(solvedQuiz);
48+
4249
Map<String, String> result = new HashMap<>();
4350
result.put("정답률", correctRate);
4451
result.put("피드백", feedback);
4552

46-
solvedQuizRepository.save(SolvedQuiz.builder()
47-
.user(userFacade.getCurrentUser())
48-
.quiz(quiz)
49-
.receivedScore(Long.valueOf(correctRate))
50-
.build());
51-
5253
return result;
5354
}
5455
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package JavaProject.Dayoung.domain.quiz.service;
2+
3+
import JavaProject.Dayoung.domain.area.domain.Area;
4+
import JavaProject.Dayoung.domain.quiz.domain.SolvedQuiz;
5+
import JavaProject.Dayoung.domain.quiz.domain.UserAreaSolved;
6+
import JavaProject.Dayoung.domain.quiz.presentation.dto.response.UserAreaSolvedResponse;
7+
import JavaProject.Dayoung.domain.quiz.repository.UserAreaSolvedRepository;
8+
import JavaProject.Dayoung.domain.user.domain.User;
9+
import lombok.RequiredArgsConstructor;
10+
import org.springframework.stereotype.Service;
11+
import org.springframework.transaction.annotation.Transactional;
12+
13+
import java.util.List;
14+
import java.util.stream.Collectors;
15+
16+
@Service
17+
@Transactional
18+
@RequiredArgsConstructor
19+
public class UserAreaSolvedService {
20+
21+
private final UserAreaSolvedRepository userAreaSolvedRepository;
22+
23+
public void updateUserAreaSolved(SolvedQuiz solvedQuiz) {
24+
User user = solvedQuiz.getUser();
25+
List<Area> areas = solvedQuiz.getQuiz().getArea();
26+
if (areas.isEmpty()) {
27+
throw new IllegalStateException("퀴즈에 지정된 분야가 없습니다.");
28+
}
29+
Area area = areas.get(0);
30+
31+
UserAreaSolved userAreaSolved = userAreaSolvedRepository.findByUserAndArea(user, area)
32+
.orElse(UserAreaSolved.builder()
33+
.user(user)
34+
.area(area)
35+
.solvedCount(0L)
36+
.build());
37+
38+
userAreaSolved.incrementSolvedCount();
39+
userAreaSolvedRepository.save(userAreaSolved);
40+
}
41+
42+
@Transactional(readOnly = true)
43+
public List<UserAreaSolvedResponse> getUserAreaSolvedStats(Long userId) {
44+
return userAreaSolvedRepository.findAllByUserId(userId).stream()
45+
.map(userAreaSolved -> UserAreaSolvedResponse.builder()
46+
.area(userAreaSolved.getArea())
47+
.solvedCount(userAreaSolved.getSolvedCount())
48+
.build())
49+
.collect(Collectors.toList());
50+
}
51+
}

0 commit comments

Comments
 (0)