Skip to content

Commit e5b23b9

Browse files
authored
refactor : 내 풀이리스트 부분 조회 (#393)
1 parent 9a0b68c commit e5b23b9

File tree

12 files changed

+176
-220
lines changed

12 files changed

+176
-220
lines changed

src/main/java/com/gamzabat/algohub/constants/BOJResultConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class BOJResultConstants {
1010
public static final String OVER_OUTPUT_LIMIT = "출력 초과";
1111
public static final String WRONG_OUTPUT_FORMAT = "출력 형식이 잘못되었습니다";
1212
public static final String WRONG_OUTPUT_FORMAT_CUSTOM = "출력 에러";
13+
public static final String SCORE_UNIT = "점";
1314

1415
private BOJResultConstants() {
1516
throw new RuntimeException("Can not instantiate : BOJResultConstants");

src/main/java/com/gamzabat/algohub/feature/solution/controller/SolutionController.java

Lines changed: 18 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import org.springframework.data.domain.PageRequest;
77
import org.springframework.data.domain.Pageable;
88
import org.springframework.data.domain.Sort;
9+
import org.springframework.data.web.PageableDefault;
910
import org.springframework.http.ResponseEntity;
1011
import org.springframework.validation.Errors;
1112
import org.springframework.web.bind.annotation.GetMapping;
13+
import org.springframework.web.bind.annotation.ModelAttribute;
1214
import org.springframework.web.bind.annotation.PathVariable;
1315
import org.springframework.web.bind.annotation.PostMapping;
1416
import org.springframework.web.bind.annotation.RequestBody;
@@ -20,8 +22,10 @@
2022
import com.gamzabat.algohub.exception.RequestException;
2123
import com.gamzabat.algohub.feature.solution.dto.CreateSolutionRequest;
2224
import com.gamzabat.algohub.feature.solution.dto.GetCurrentSolvingStatusResponse;
25+
import com.gamzabat.algohub.feature.solution.dto.GetMySolutionListRequest;
26+
import com.gamzabat.algohub.feature.solution.dto.GetSolutionListRequest;
2327
import com.gamzabat.algohub.feature.solution.dto.GetSolutionResponse;
24-
import com.gamzabat.algohub.feature.solution.dto.GetSolutionWithGroupIdResponse;
28+
import com.gamzabat.algohub.feature.solution.enums.ProgressCategory;
2529
import com.gamzabat.algohub.feature.solution.service.SolutionService;
2630
import com.gamzabat.algohub.feature.user.domain.User;
2731

@@ -41,14 +45,9 @@ public class SolutionController {
4145
@Operation(summary = "풀이 목록 조회 API", description = "특정 문제에 대한 풀이를 모두 조회하는 API")
4246
public ResponseEntity<Page<GetSolutionResponse>> getSolutionList(@AuthedUser User user,
4347
@PathVariable Long problemId,
44-
@RequestParam(required = false) String language,
45-
@RequestParam(required = false) String result,
46-
@RequestParam(required = false) String nickname,
47-
@RequestParam(defaultValue = "0") int page,
48-
@RequestParam(defaultValue = "20") int size) {
49-
Pageable pageable = PageRequest.of(page, size);
50-
Page<GetSolutionResponse> response = solutionService.getSolutionList(user, problemId, nickname, language,
51-
result, pageable);
48+
@ModelAttribute GetSolutionListRequest request,
49+
@PageableDefault(size = 20, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
50+
Page<GetSolutionResponse> response = solutionService.getSolutionList(user, problemId,request,pageable);
5251
return ResponseEntity.ok().body(response);
5352
}
5453

@@ -69,69 +68,21 @@ public ResponseEntity<Void> createSolution(@Valid @RequestBody CreateSolutionReq
6968
return ResponseEntity.ok().build();
7069
}
7170

72-
@GetMapping("/groups/{groupId}/my-solutions/in-progress")
73-
@Operation(summary = "그룹 내 진행 중인 나의 풀이 전체 조회 API", description = "특정 그룹 내에서 진행 중인 문제에 대해 제출한 나의 풀이 모두 조회하는 API")
74-
public ResponseEntity<Page<GetSolutionResponse>> getMySolutionsInGroupInProgress(@AuthedUser User user,
75-
@PathVariable Long groupId,
76-
@RequestParam(required = false) Integer problemNumber,
77-
@RequestParam(required = false) String language,
78-
@RequestParam(required = false) String result,
79-
@RequestParam(defaultValue = "0") int page,
80-
@RequestParam(defaultValue = "20") int size) {
81-
Pageable pageable = PageRequest.of(page, size);
82-
Page<GetSolutionResponse> response = solutionService.getMySolutionsInGroupInProgress(user,
83-
groupId, problemNumber, language, result, pageable);
84-
return ResponseEntity.ok().body(response);
85-
}
86-
87-
@GetMapping("/groups/{groupId}/my-solutions/expired")
88-
@Operation(summary = "그룹 내 마감된 나의 풀이 전체 조회 API", description = "특정 그룹 내에서 마감한 문제에 대해 제출한 나의 풀이를 모두 조회하는 API")
89-
public ResponseEntity<Page<GetSolutionResponse>> getMySolutionsInGroupExpired(@AuthedUser User user,
90-
@PathVariable Long groupId,
91-
@RequestParam(required = false) Integer problemNumber,
92-
@RequestParam(required = false) String language,
93-
@RequestParam(required = false) String result,
94-
@RequestParam(defaultValue = "0") int page,
95-
@RequestParam(defaultValue = "20") int size) {
96-
Pageable pageable = PageRequest.of(page, size);
97-
Page<GetSolutionResponse> response = solutionService.getMySolutionsInGroupExpired(user,
98-
groupId, problemNumber, language, result, pageable);
99-
return ResponseEntity.ok().body(response);
100-
}
101-
102-
@GetMapping("/users/my-solutions/in-progress")
103-
@Operation(summary = "진행 중인 내 풀이 전체 조회 API", description = "그룹 상관 없이 진행 중인 문제에 대한 나의 풀이 전체를 조회하는 API")
104-
public ResponseEntity<Page<GetSolutionWithGroupIdResponse>> getMySolutionsInProgress(@AuthedUser User user,
105-
@RequestParam(required = false) Integer problemNumber,
106-
@RequestParam(required = false) String language,
107-
@RequestParam(required = false) String result,
108-
@RequestParam(defaultValue = "0") int page,
109-
@RequestParam(defaultValue = "20") int size) {
110-
Pageable pageable = PageRequest.of(page, size);
111-
Page<GetSolutionWithGroupIdResponse> response = solutionService.getMySolutionsInProgress(user,
112-
problemNumber, language, result, pageable);
113-
return ResponseEntity.ok().body(response);
114-
}
115-
116-
@GetMapping("/users/my-solutions/expired")
117-
@Operation(summary = "마감 된 내 풀이 전체 조회 API", description = "그룹 상관 없이 나의 풀이 전체를 조회하는 API")
118-
public ResponseEntity<Page<GetSolutionWithGroupIdResponse>> getMySolutions(@AuthedUser User user,
119-
@RequestParam(required = false) Integer problemNumber,
120-
@RequestParam(required = false) String language,
121-
@RequestParam(required = false) String result,
122-
@RequestParam(defaultValue = "0") int page,
123-
@RequestParam(defaultValue = "20") int size) {
124-
Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
125-
Page<GetSolutionWithGroupIdResponse> response = solutionService.getMySolutionsExpired(user,
126-
problemNumber, language, result, pageable);
127-
return ResponseEntity.ok().body(response);
128-
}
129-
13071
@GetMapping("/groups/{groupId}/solutions/current-status")
13172
@Operation(summary = "풀이 현황 테이블 조회 API", description = "진행 중인 문제들에 대해 풀이 현황 테이블을 조회하는 API")
13273
public ResponseEntity<List<GetCurrentSolvingStatusResponse>> getCurrentSolvingStatus(@AuthedUser User user,
13374
@PathVariable Long groupId) {
13475
List<GetCurrentSolvingStatusResponse> response = solutionService.getCurrentSolvingStatuses(user, groupId);
13576
return ResponseEntity.ok().body(response);
13677
}
78+
79+
@GetMapping("/solutions/me")
80+
@Operation(summary = "내 풀이 전체 조회", description = "나의 풀이를 그룹, 문제 번호, 언어, 결과, 상태 등으로 필터링하여 조회하는 API")
81+
public ResponseEntity<Page<GetSolutionResponse>> getMySolutionList(@AuthedUser User user,
82+
@ModelAttribute GetMySolutionListRequest request,
83+
@PageableDefault(size = 20, sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable) {
84+
Page<GetSolutionResponse> response = solutionService.getMySolutionList(user, request.groupId(),
85+
request.problemNumber(), request.language(), request.result(), request.status(), request.isIncorrect(), pageable);
86+
return ResponseEntity.ok().body(response);
87+
}
13788
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.gamzabat.algohub.feature.solution.dto;
2+
3+
import org.springframework.web.bind.annotation.RequestParam;
4+
5+
import com.gamzabat.algohub.feature.solution.enums.ProgressCategory;
6+
7+
import lombok.Builder;
8+
9+
@Builder
10+
public record GetMySolutionListRequest(Long groupId,
11+
Integer problemNumber,
12+
String language,
13+
String result,
14+
ProgressCategory status,
15+
Boolean isIncorrect) {
16+
}

src/main/java/com/gamzabat/algohub/feature/solution/dto/GetMySolutionListResponse.java

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.gamzabat.algohub.feature.solution.dto;
2+
3+
import lombok.Builder;
4+
5+
@Builder
6+
public record GetSolutionListRequest( String language,
7+
String result,
8+
String nickname) {
9+
}

src/main/java/com/gamzabat/algohub/feature/solution/dto/GetSolutionResponse.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class GetSolutionResponse {
2828
private final Integer codeLength;
2929
private final Long commentCount;
3030
private final Boolean isRead;
31+
private final Long groupId;
3132

3233
public static GetSolutionResponse toDTO(Solution solution, Integer accuracy, Integer submitMemberCount,
3334
Integer totalMemberCount, Long commentCount, Boolean isRead) {
@@ -50,6 +51,7 @@ public static GetSolutionResponse toDTO(Solution solution, Integer accuracy, Int
5051
.codeLength(solution.getCodeLength())
5152
.commentCount(commentCount)
5253
.isRead(isRead)
54+
.groupId(solution.getProblem().getStudyGroup().getId())
5355
.build();
5456
}
5557

src/main/java/com/gamzabat/algohub/feature/solution/dto/GetSolutionWithGroupIdResponse.java

Lines changed: 0 additions & 37 deletions
This file was deleted.

src/main/java/com/gamzabat/algohub/feature/solution/repository/querydsl/CustomSolutionRepository.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,13 @@ Page<Solution> findAllFilteredMySolutions(
3434
ProgressCategory category,
3535
Pageable pageable);
3636

37+
Page<Solution> findAllFilteredMySolutionsIsIncorrect(
38+
User user,
39+
Integer problemNumber,
40+
String language,
41+
String result,
42+
ProgressCategory category,
43+
Pageable pageable);
44+
3745
boolean existsByUserAndProblemAndResult(User user, Problem problem, String result);
3846
}

src/main/java/com/gamzabat/algohub/feature/solution/repository/querydsl/CustomSolutionRepositoryImpl.java

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.gamzabat.algohub.feature.solution.domain.Solution;
1919
import com.gamzabat.algohub.feature.solution.enums.ProgressCategory;
2020
import com.gamzabat.algohub.feature.user.domain.User;
21+
import com.querydsl.core.types.dsl.BooleanExpression;
2122
import com.querydsl.jpa.impl.JPAQuery;
2223
import com.querydsl.jpa.impl.JPAQueryFactory;
2324

@@ -71,7 +72,8 @@ public Page<Solution> findAllFilteredMySolutionsInGroup(User user, StudyGroup gr
7172
.and(solution.user.eq(user)))
7273
.orderBy(solution.solvedDateTime.desc());
7374

74-
addMySolutionFilters(problemNumber, language, result, category, query);
75+
addMySolutionFiltersExceptResult(problemNumber, language, category, query);
76+
addResultFilter(result, query);
7577
query.offset(pageable.getOffset())
7678
.limit(pageable.getPageSize());
7779

@@ -88,29 +90,56 @@ public Page<Solution> findAllFilteredMySolutions(User user, Integer problemNumbe
8890
.and(solution.deletedAt.isNull()))
8991
.orderBy(solution.solvedDateTime.desc());
9092

91-
addMySolutionFilters(problemNumber, language, result, category, query);
93+
addMySolutionFiltersExceptResult(problemNumber, language, category, query);
94+
addResultFilter(result, query);
9295
query.offset(pageable.getOffset())
9396
.limit(pageable.getPageSize());
9497

9598
JPAQuery<Long> countQuery = solutionCountQuery(query);
9699
return PageableExecutionUtils.getPage(query.fetch(), pageable, countQuery::fetchOne);
97100
}
98101

99-
private void addMySolutionFilters(Integer problemNumber, String language, String result, ProgressCategory category,
102+
@Override
103+
public Page<Solution> findAllFilteredMySolutionsIsIncorrect(User user,
104+
Integer problemNumber,
105+
String language,
106+
String result,
107+
ProgressCategory category,
108+
Pageable pageable) {
109+
JPAQuery<Solution> query = queryFactory.selectFrom(solution)
110+
.where(solution.user.eq(user)
111+
.and(solution.deletedAt.isNull()))
112+
.orderBy(solution.solvedDateTime.desc());
113+
addMySolutionFiltersExceptResult(problemNumber, language, category, query);
114+
addResultIncorrectFilter(result, query);
115+
query.offset(pageable.getOffset())
116+
.limit(pageable.getPageSize());
117+
JPAQuery<Long> countQuery = solutionCountQuery(query);
118+
return PageableExecutionUtils.getPage(query.fetch(), pageable, countQuery::fetchOne);
119+
}
120+
121+
private void addMySolutionFiltersExceptResult(Integer problemNumber, String language, ProgressCategory category,
100122
JPAQuery<Solution> query) {
101123
addEndDateFilter(category, query);
102124
addProblemFilter(problemNumber, query);
103125
addLanguageFilter(language, query);
104-
addResultFilter(result, query);
105126
}
106127

107128
private void addEndDateFilter(ProgressCategory category, JPAQuery<Solution> query) {
129+
if (category == null) return;
108130
if (category.equals(ProgressCategory.IN_PROGRESS))
109131
query.where(problem.endDate.goe(LocalDate.now()));
110132
else if (category.equals(ProgressCategory.EXPIRED))
111133
query.where(problem.endDate.before(LocalDate.now()));
112134
}
113135

136+
private void addResultIncorrectFilter(String result, JPAQuery<Solution> query) {
137+
BooleanExpression incorrectBase =
138+
solution.result.isNotNull()
139+
.and(solution.result.ne(CORRECT))
140+
.and(solution.result.endsWith(SCORE_UNIT).not());
141+
query.where(incorrectBase);
142+
}
114143
private void addResultFilter(String result, JPAQuery<Solution> query) {
115144
if (result != null && !result.isBlank()) {
116145
if (result.equals(CORRECT))

0 commit comments

Comments
 (0)