Skip to content

Commit

Permalink
feat: (#47) 이슈 검색 필터 구현 완료
Browse files Browse the repository at this point in the history
  • Loading branch information
eNoLJ committed Jun 15, 2021
1 parent 8b87782 commit 1727954
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

public interface CustomizedIssueRepository {

List<Issue> findAllIssuesFilteredBy(SearchRequestDTO searchRequest);
List<Issue> findAllIssuesFilteredBySearchRequest(SearchRequestDTO searchRequest);

// List<Issue> findAllIssuesFilteredBy(SearchRequest searchRequest);
long countIssueFilteredByStatusAndSearchRequest(String status, SearchRequestDTO searchRequest);
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.issuetracker.domain.issue;


import com.issuetracker.domain.label.Label;
import com.issuetracker.domain.user.User;
import com.issuetracker.web.dto.reqeust.SearchRequestDTO;
import com.issuetracker.web.dto.vo.Status;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;

Expand All @@ -22,7 +23,19 @@ public class CustomizedIssueRepositoryImpl implements CustomizedIssueRepository

private final JPAQueryFactory queryFactory;

public List<Issue> findAllIssuesFilteredBy(SearchRequestDTO searchRequest) {
public List<Issue> findAllIssuesFilteredBySearchRequest(SearchRequestDTO searchRequest) {
return findAllIssuesFilteredByStatusAndSearchRequest(searchRequest.getStatus(), searchRequest);
}

private List<Issue> findAllIssuesFilteredByStatusAndSearchRequest(String status, SearchRequestDTO searchRequest) {
return findIssuesByStatusAndSearchRequest(status, searchRequest).limit(100).fetch();
}

public long countIssueFilteredByStatusAndSearchRequest(String status, SearchRequestDTO searchRequest) {
return findIssuesByStatusAndSearchRequest(status, searchRequest).fetchCount();
}

private JPAQuery<Issue> findIssuesByStatusAndSearchRequest(String status, SearchRequestDTO searchRequest) {
return queryFactory
.select(issue)
.distinct()
Expand All @@ -31,38 +44,29 @@ public List<Issue> findAllIssuesFilteredBy(SearchRequestDTO searchRequest) {
.leftJoin(issue.labels, label)
.leftJoin(issue.milestone, milestone)
.leftJoin(issue.comments, comment1)
.where(statusEquals(searchRequest.getStatus()),
.where(
statusEquals(status),
authorEquals(searchRequest.getAuthor()),
// labelEquals(labelName),
labelEquals(searchRequest.getLabel()),
milestoneEquals(searchRequest.getMilestone()),
assigneeEquals(searchRequest.getAssignee()),
commenterEquals(searchRequest.getCommenter()))
.limit(100)
.fetch();

// return queryFactory
// .selectFrom(issue)
// .where(
// statusEquals(searchRequest.getStatus()),
// authorEquals(searchRequest.getAuthor()),
// assigneeEquals(searchRequest.getAssignee())
// )
// .fetch();
commenterEquals(searchRequest.getCommenter())
);
}

public BooleanExpression statusEquals(String status) {
private BooleanExpression statusEquals(String status) {
return hasText(status) ? issue.isOpen.eq(Status.statusToBoolean(status)) : null;
}

public BooleanExpression authorEquals(String author) {
private BooleanExpression authorEquals(String author) {
return hasText(author) ? user.userName.eq(author) : null;
}

public BooleanExpression milestoneEquals(String milestoneTitle) {
private BooleanExpression milestoneEquals(String milestoneTitle) {
return hasText(milestoneTitle) ? milestone.title.eq(milestoneTitle) : null;
}

public BooleanExpression assigneeEquals(String assignee) {
private BooleanExpression assigneeEquals(String assignee) {
if (!hasText(assignee)) {
return null;
}
Expand All @@ -86,11 +90,20 @@ private User findByUserName(String userName) {
.fetchFirst();
}

// public BooleanExpression commenterEquals(User commenter) {
// return commenter != null ? issue.comments.contains(commenter) : null;
// }
//
// public BooleanExpression labelEquals(List<String> label) {
// return label!=null?
// }
public BooleanExpression labelEquals(List<String> labels) {
if (labels.isEmpty()) {
return null;
}
List<Label> labelsList = getLabels(labels);
if (labelsList.isEmpty()) {
return null;
}
return label.in(labelsList);
}

public List<Label> getLabels(List<String> labels) {
return queryFactory.selectFrom(label)
.where(label.name.in(labels))
.fetch();
}
}
13 changes: 13 additions & 0 deletions BE/src/main/java/com/issuetracker/domain/user/UserRepository.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
package com.issuetracker.domain.user;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

Optional<User> findByUserName(String userName);

@Modifying
@Query(value = "select * from user where id in (select distinct assignees_id from issue_assignees)",
nativeQuery = true)
List<User> findAssignees();

@Modifying
@Query(value = "select * from user where id in (select distinct author_id from issue)",
nativeQuery = true)
List<User> findAuthors();
}
26 changes: 6 additions & 20 deletions BE/src/main/java/com/issuetracker/service/IssueService.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import com.issuetracker.exception.ElementNotFoundException;
import com.issuetracker.web.dto.vo.Assignee;
import com.issuetracker.web.dto.vo.Count;
import com.issuetracker.web.dto.vo.SearchRequest;
import com.issuetracker.web.dto.vo.Status;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -19,6 +18,9 @@
import java.util.List;
import java.util.stream.Collectors;

import static com.issuetracker.web.dto.vo.Status.CLOSE;
import static com.issuetracker.web.dto.vo.Status.OPEN;

@Service
@RequiredArgsConstructor
public class IssueService {
Expand All @@ -29,34 +31,18 @@ public class IssueService {
private final UserService userService;

public IssuesResponseDTO getIssues(SearchRequestDTO searchRequestDTO) {

// SearchRequest searchRequest = new SearchRequest(
// Status.statusToBoolean(searchRequestDTO.getStatus()),
// searchRequestDTO.getAuthor(),
// userService.findNullableUserByUserName(searchRequestDTO.getAssignee()),
// userService.findNullableUserByUserName(searchRequestDTO.getCommenter()),
// searchRequestDTO.getLabel(),
// milestoneService.findNullableMilestoneByTitle(searchRequestDTO.getMilestone())
// );

Count count = Count.builder()
.label((int) labelService.count())
.milestone((int) milestoneService.count())
.openedIssue((int) issueRepository.countAllByIsOpenTrue())
.closedIssue((int) issueRepository.countAllByIsOpenFalse())
.openedIssue((int) issueRepository.countIssueFilteredByStatusAndSearchRequest(OPEN.getName(), searchRequestDTO))
.closedIssue((int) issueRepository.countIssueFilteredByStatusAndSearchRequest(CLOSE.getName(), searchRequestDTO))
.build();

List<IssueResponseDTO> issues = issueRepository.findAllIssuesFilteredBy(searchRequestDTO).stream()
List<IssueResponseDTO> issues = issueRepository.findAllIssuesFilteredBySearchRequest(searchRequestDTO).stream()
.map(issue -> IssueResponseDTO.of(issue, userService.usersToAssignees(issue), labelService.labelsToLabelDTOs(issue)))
.collect(Collectors.toList());
return IssuesResponseDTO.of(count, issues);
}

private List<Issue> filterByStatus(String status) {
boolean newStatus = Status.statusToBoolean(status);
return newStatus ? issueRepository.findAllByIsOpenTrue() : issueRepository.findAllByIsOpenFalse();
}

@Transactional
public void changeIssueStatus(IssueNumbersRequestDTO requestDTO, String status) {
boolean newStatus = !Status.statusToBoolean(status);
Expand Down
20 changes: 18 additions & 2 deletions BE/src/main/java/com/issuetracker/service/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@
import com.issuetracker.domain.user.UserRepository;
import com.issuetracker.exception.InvalidSearchRequestException;
import com.issuetracker.exception.UserNotFoundException;
import com.issuetracker.web.dto.response.AssigneesResponseDTO;
import com.issuetracker.web.dto.response.AuthorsResponseDTO;
import com.issuetracker.web.dto.response.UserResponseDTO;
import com.issuetracker.web.dto.vo.Assignee;
import com.issuetracker.domain.issue.Issue;
import com.issuetracker.web.dto.vo.Author;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
Expand Down Expand Up @@ -55,10 +57,24 @@ public User findUserById(Long id) {

public List<Assignee> usersToAssignees(Issue issue) {
return userRepository.findAll().stream()
.map(user -> Assignee.of(user, issue, checkAssignees(user, issue)))
.map(user -> Assignee.of(user, checkAssignees(user, issue)))
.collect(Collectors.toList());
}

public AssigneesResponseDTO getAssignees() {
List<Assignee> assignees = userRepository.findAssignees().stream()
.map(Assignee::of)
.collect(Collectors.toList());
return new AssigneesResponseDTO(assignees);
}

public AuthorsResponseDTO getAuthors() {
List<Author> authors = userRepository.findAuthors().stream()
.map(Author::of)
.collect(Collectors.toList());
return new AuthorsResponseDTO(authors);
}

private boolean checkAssignees(User user, Issue issue) {
long count = issue.getAssignees().stream()
.filter(assignee -> assignee.equals(user))
Expand Down
14 changes: 14 additions & 0 deletions BE/src/main/java/com/issuetracker/web/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.issuetracker.auth.annotation.UserId;
import com.issuetracker.auth.dto.UserAgentDTO;
import com.issuetracker.service.UserService;
import com.issuetracker.web.dto.response.AssigneesResponseDTO;
import com.issuetracker.web.dto.response.AuthorsResponseDTO;
import com.issuetracker.web.dto.response.UserResponseDTO;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
Expand Down Expand Up @@ -31,4 +33,16 @@ public void logout(@UserId Long userId) {
logger.debug("로그아웃 요청");
userService.logout(userId);
}

@GetMapping("/assignees")
public AssigneesResponseDTO getAssignees() {
logger.debug("모든 담당자 조회");
return userService.getAssignees();
}

@GetMapping("/authors")
public AuthorsResponseDTO getAuthors() {
logger.debug("모든 작성자 조회");
return userService.getAuthors();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.issuetracker.web.dto.response;

import com.issuetracker.web.dto.vo.Author;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

import java.util.List;

@Getter
@RequiredArgsConstructor
public class AuthorsResponseDTO {

private final List<Author> authors;
}
3 changes: 1 addition & 2 deletions BE/src/main/java/com/issuetracker/web/dto/vo/Assignee.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.issuetracker.web.dto.vo;

import com.issuetracker.domain.issue.Issue;
import com.issuetracker.domain.user.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
Expand All @@ -18,7 +17,7 @@ public class Assignee {
private final String userName;
private final boolean isAssigned;

public static Assignee of(User user, Issue issue, boolean isAssigned) {
public static Assignee of(User user, boolean isAssigned) {
return Assignee.builder()
.id(user.getId())
.image(user.getAvatarUrl())
Expand Down
24 changes: 24 additions & 0 deletions BE/src/main/java/com/issuetracker/web/dto/vo/Author.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.issuetracker.web.dto.vo;

import com.issuetracker.domain.user.User;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
@AllArgsConstructor
public class Author {

private final Long id;
private final String image;
private final String userName;

public static Author of(User user) {
return Author.builder()
.id(user.getId())
.image(user.getAvatarUrl())
.userName(user.getUserName())
.build();
}
}
1 change: 1 addition & 0 deletions BE/src/main/java/com/issuetracker/web/dto/vo/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@Getter
@RequiredArgsConstructor
public enum Status {

OPEN("open"),
CLOSE("close");

Expand Down

0 comments on commit 1727954

Please sign in to comment.