Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 이슈 조회 API 구현(이슈 목록 조회 API 제외) #89

Merged
merged 8 commits into from
Aug 14, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,6 @@ public Optional<Comment> findExistCommentById(Long commentId) {
.userId(rs.getLong("user_id"))
.issueId(rs.getLong("issue_id"))
.content(rs.getString("content"))
.createdAt(rs.getTimestamp("created_At").toLocalDateTime())
.createdAt(rs.getTimestamp("created_at").toLocalDateTime())
.build());
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,11 @@ public enum ErrorCode implements StatusCode {

// -- [Issue] -- //
DUPLICATE_OBJECT_FOUND(HttpStatus.BAD_REQUEST, "중복된 항목 선택입니다."),
NOT_EXIST_ISSUE(HttpStatus.BAD_REQUEST, "존재하지 않는 이슈입니다."),
ALREADY_DELETED_ISSUE(HttpStatus.BAD_REQUEST, "이미 삭제된 이슈입니다."),
NOT_FOUND_ISSUES(HttpStatus.BAD_REQUEST, "이슈를 찾을 수 없습니다.");


private HttpStatus status;
private String message;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

import static codesquad.issueTracker.global.exception.SuccessCode.*;

import codesquad.issueTracker.issue.dto.IssueLabelResponseDto;
import codesquad.issueTracker.issue.dto.IssueMilestoneResponseDto;
import codesquad.issueTracker.issue.dto.IssueOptionResponseDto;
import codesquad.issueTracker.issue.dto.IssueResponseDto;
import codesquad.issueTracker.issue.dto.IssueUserResponseDto;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down Expand Up @@ -35,12 +42,42 @@ public class IssueController {

@PostMapping("/issues")
public ApiResponse<String> postIssues(@Valid @RequestBody IssueWriteRequestDto request,
HttpServletRequest httpServletRequest) {
HttpServletRequest httpServletRequest) {
Long id = Long.parseLong(String.valueOf(httpServletRequest.getAttribute("userId")));
issueService.save(request, id);
return ApiResponse.success(SUCCESS.getStatus(), SUCCESS.getMessage());
}


@GetMapping("/issues/labels")
public ApiResponse<List<IssueLabelResponseDto>> getIssueLabels() {
List<IssueLabelResponseDto> labels = issueService.getIssueLabels();
return ApiResponse.success(SUCCESS.getStatus(), labels);
}

@GetMapping("/issues/milestones")
public ApiResponse<List<IssueMilestoneResponseDto>> getIssueMilestones() {
List<IssueMilestoneResponseDto> milestones = issueService.getIssueMilestones();
return ApiResponse.success(SUCCESS.getStatus(), milestones);
}

@GetMapping("/issues/participants")
public ApiResponse<List<IssueUserResponseDto>> getIssueUsers() {
List<IssueUserResponseDto> participants = issueService.getIssueUsers();
return ApiResponse.success(SUCCESS.getStatus(), participants);
}

@GetMapping("/issues/{issueId}")
public ApiResponse<IssueResponseDto> getIssue(@PathVariable Long issueId) {
IssueResponseDto issueResponseDto = issueService.getIssueById(issueId);
return ApiResponse.success(SUCCESS.getStatus(), issueResponseDto);
}

@GetMapping("/issues/{issueId}/options")
public ApiResponse<IssueOptionResponseDto> getIssueOptions(@PathVariable Long issueId) {
IssueOptionResponseDto issueOptionResponseDto = issueService.getIssueOptions(issueId);
return ApiResponse.success(SUCCESS.getStatus(), issueOptionResponseDto);

@PatchMapping("/issues/status")
public ApiResponse<String> patchStatus(@RequestBody ModifyIssueStatusRequestDto request) {
issueService.modifyIssueStatus(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package codesquad.issueTracker.issue.dto;

import codesquad.issueTracker.label.vo.LabelVo;
import lombok.Builder;
import lombok.Getter;

@Getter
public class IssueLabelResponseDto {
private Long id;
private String name;
private String backgroundColor;
private String textColor;

@Builder
public IssueLabelResponseDto(Long id, String name, String backgroundColor, String textColor) {
this.id = id;
this.name = name;
this.backgroundColor = backgroundColor;
this.textColor = textColor;
}

public static IssueLabelResponseDto from(LabelVo label) {
return IssueLabelResponseDto.builder()
.id(label.getId())
.name(label.getName())
.backgroundColor(label.getBackgroundColor())
.textColor(label.getTextColor())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package codesquad.issueTracker.issue.dto;

import codesquad.issueTracker.milestone.vo.MilestoneVo;
import lombok.Builder;
import lombok.Getter;

@Getter
public class IssueMilestoneResponseDto {
private Long id;
private String name;

@Builder
public IssueMilestoneResponseDto(Long id, String name) {
this.id = id;
this.name = name;
}

public static IssueMilestoneResponseDto from(MilestoneVo milestoneVo) {
return builder()
.id(milestoneVo.getId())
.name(milestoneVo.getName())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package codesquad.issueTracker.issue.dto;

import codesquad.issueTracker.issue.vo.IssueLabelVo;
import codesquad.issueTracker.issue.vo.IssueMilestoneVo;
import codesquad.issueTracker.issue.vo.AssigneeVo;
import java.util.List;
import lombok.Builder;
import lombok.Getter;

@Getter
public class IssueOptionResponseDto {

private List<AssigneeVo> assignees;
private List<IssueLabelVo> labels;
private IssueMilestoneVo milestone;

@Builder
public IssueOptionResponseDto(List<AssigneeVo> assignees, List<IssueLabelVo> labels, IssueMilestoneVo milestone) {
this.assignees = assignees;
this.labels = labels;
this.milestone = milestone;
}

public static IssueOptionResponseDto of(List<AssigneeVo> assignees, List<IssueLabelVo> labels, IssueMilestoneVo milestone) {
if (milestone.getId() == null) {
return IssueOptionResponseDto.builder()
.assignees(assignees)
.labels(labels)
.build();
}

return IssueOptionResponseDto.builder()
.assignees(assignees)
.labels(labels)
.milestone(milestone)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package codesquad.issueTracker.issue.dto;

import codesquad.issueTracker.issue.domain.Issue;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Getter;

@Getter
public class IssueResponseDto {

private Long id;
private String title;
private String content;
private LocalDateTime createdAt;
private boolean isClose;

@Builder
public IssueResponseDto(Long id, String title, String content, LocalDateTime createdAt, boolean isClose) {
this.id = id;
this.title = title;
this.content = content;
this.createdAt = createdAt;
this.isClose = isClose;
}

public static IssueResponseDto from(Issue issue) {
return IssueResponseDto.builder()
.id(issue.getId())
.title(issue.getTitle())
.content(issue.getContent())
.createdAt(issue.getCreatedAt())
.isClose(issue.getIsClosed())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package codesquad.issueTracker.issue.dto;

import codesquad.issueTracker.user.domain.User;
import lombok.Builder;
import lombok.Getter;

@Getter
public class IssueUserResponseDto {
private Long id;
private String name;
private String imageUrl;

@Builder
public IssueUserResponseDto(Long id, String name, String imageUrl) {
this.id = id;
this.name = name;
this.imageUrl = imageUrl;
}

public static IssueUserResponseDto from(User user) {
return IssueUserResponseDto.builder()
.id(user.getId())
.name(user.getName())
.imageUrl(user.getProfileImg())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package codesquad.issueTracker.issue.repository;

import java.time.LocalDateTime;

import codesquad.issueTracker.issue.vo.AssigneeVo;
import codesquad.issueTracker.issue.vo.IssueMilestoneVo;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.time.LocalDateTime;



import org.springframework.dao.support.DataAccessUtils;
import org.springframework.jdbc.core.JdbcTemplate;
Expand Down Expand Up @@ -56,6 +62,59 @@ public Long insertAssignees(Long issueId, Long userId) {
return keyHolder.getKey().longValue();
}


public Optional<Issue> findActiveIssueById(Long issueId) {
String sql = "SELECT * FROM issues WHERE id = :issueId AND is_deleted = false";
return Optional.ofNullable(
DataAccessUtils.singleResult(
jdbcTemplate.query(sql, Map.of("issueId", issueId), issueRowMapper)));
}

private final RowMapper<Issue> issueRowMapper = ((rs, rowNum) -> Issue.builder()
.id(rs.getLong("id"))
.title(rs.getString("title"))
.content(rs.getString("content"))
.createdAt(rs.getTimestamp("created_at").toLocalDateTime())
.isClosed(rs.isClosed())
.build());

public Optional<Issue> findById(Long issueId) {
String sql = "SELECT * FROM issues WHERE id = :issueId";
return Optional.ofNullable(
DataAccessUtils.singleResult(
jdbcTemplate.query(sql, Map.of("issueId", issueId), issueRowMapper)));
}

public List<AssigneeVo> findAssigneesById(Long issueId) {
String sql = "select u.id, u.name, u.profile_img "
+ "from assignees a "
+ " join users u on a.user_id = u.id "
+ " join issues i on a.issue_id = i.user_id "
+ "where i.id = :issueId "
+ "AND i.is_deleted = false";
return jdbcTemplate.query(sql, Map.of("issueId",issueId), assigneeVoRowMapper);
}

private final RowMapper<AssigneeVo> assigneeVoRowMapper = ((rs, rowNum) -> AssigneeVo.builder()
.id(rs.getLong("id"))
.name(rs.getString("name"))
.imgUrl(rs.getString("profile_img"))
.build());


public int findCountByStatusAndMilestone(boolean status, IssueMilestoneVo milestone) {
String sql = "select COUNT(i.id) as count "
+ "from issues i "
+ " join milestones m on m.id = i.milestone_id "
+ "where m.id = :milestoneId "
+ "and i.is_deleted = false "
+ "and i.is_closed = :status";
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue("milestoneId", milestone.getId());
params.addValue("status", status);
return jdbcTemplate.queryForObject(sql, params, Integer.class);
}

public Optional<Issue> findById(Long id) {
String sql = "SELECT id, milestone_id, user_id, title, content, created_at, is_closed FROM issues WHERE id = :id AND is_deleted = 0";
return Optional.ofNullable(
Expand Down Expand Up @@ -89,7 +148,6 @@ public Long updateContent(Long id, String modifiedContent) {
.addValue("modifiedContent", modifiedContent);
jdbcTemplate.update(sql, parameterSource);
return id;

}

public Long updateTitle(Long id, String modifiedTitle) {
Expand Down Expand Up @@ -125,4 +183,5 @@ public Long updateMilestone(Long issueId, Long milestoneId) {
jdbcTemplate.update(sql, parameterSource);
return issueId;
}

}
Loading