Skip to content

Commit f9f6ea2

Browse files
committed
CLAP-55 Feat: 사용자가 요청한 작업 목록 조회
1 parent ade9427 commit f9f6ea2

File tree

11 files changed

+200
-5
lines changed

11 files changed

+200
-5
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package clap.server.adapter.inbound.web.dto.task;
2+
3+
4+
public record FindTaskListRequest(
5+
Integer term, //조회기간
6+
Long categoryId,
7+
Long mainCategoryId,
8+
String title,
9+
String nickName, //처리자 닉네임
10+
Long statusId //1,2,3,4,5 중 하나
11+
) {
12+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package clap.server.adapter.inbound.web.dto.task;
2+
3+
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
4+
5+
import java.time.LocalDateTime;
6+
7+
public record FindTaskListResponse(
8+
Long taskId,
9+
String taskCode,
10+
LocalDateTime createdAt,
11+
String mainCategoryName,
12+
String categoryName,
13+
String title,
14+
String processorName,
15+
TaskStatus taskStatus,
16+
LocalDateTime completedAt
17+
) {
18+
}

src/main/java/clap/server/adapter/inbound/web/task/TaskController.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package clap.server.adapter.inbound.web.task;
22

33
import clap.server.adapter.inbound.web.dto.task.CreateTaskRequest;
4+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
45
import clap.server.application.port.inbound.task.TaskUsecase;
56
import clap.server.common.annotation.architecture.WebAdapter;
67
import jakarta.validation.Valid;
78
import lombok.RequiredArgsConstructor;
9+
import org.springframework.data.domain.PageRequest;
10+
import org.springframework.data.domain.Pageable;
811
import org.springframework.http.ResponseEntity;
912
import org.springframework.web.bind.annotation.*;
1013

@@ -16,12 +19,20 @@
1619
public class TaskController {
1720

1821
private final TaskUsecase taskUsecase;
22+
private static final Long memberId = 4L;
1923

2024
@PostMapping
2125
public ResponseEntity<?> createTask(
2226
@RequestBody @Valid CreateTaskRequest createTaskRequest){
23-
24-
final Long memberId = 4L;
2527
return ResponseEntity.ok(taskUsecase.createTask(memberId, createTaskRequest));
2628
}
29+
30+
@GetMapping("/requests")
31+
public ResponseEntity<?> getRequestedTaskList(
32+
@RequestParam(defaultValue = "0") int page,
33+
@RequestParam(defaultValue = "20") int size,
34+
@RequestBody FindTaskListRequest findTaskListRequest){
35+
Pageable pageable = PageRequest.of(page, size);
36+
return ResponseEntity.ok(taskUsecase.findRequestedTaskList(memberId, pageable, findTaskListRequest));
37+
}
2738
}
Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
11
package clap.server.adapter.outbound.persistense;
22

3+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
4+
import clap.server.adapter.inbound.web.dto.task.FindTaskListResponse;
35
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
46
import clap.server.adapter.outbound.persistense.mapper.TaskPersistenceMapper;
57
import clap.server.adapter.outbound.persistense.repository.task.TaskRepository;
68
import clap.server.application.port.outbound.task.CommandTaskPort;
9+
import clap.server.application.port.outbound.task.LoadTaskPort;
710
import clap.server.common.annotation.architecture.PersistenceAdapter;
811

912
import clap.server.domain.model.task.Task;
1013
import lombok.RequiredArgsConstructor;
14+
import org.springframework.data.domain.Page;
15+
import org.springframework.data.domain.Pageable;
1116

17+
import java.util.Optional;
1218

1319

1420
@PersistenceAdapter
1521
@RequiredArgsConstructor
16-
public class TaskPersistenceAdapter implements CommandTaskPort {
22+
public class TaskPersistenceAdapter implements CommandTaskPort , LoadTaskPort {
1723
private final TaskRepository taskRepository;
1824
private final TaskPersistenceMapper taskPersistenceMapper;
1925
@Override
@@ -22,4 +28,30 @@ public Task save(Task task) {
2228
TaskEntity savedTaskEntity = taskRepository.save(taskEntity);
2329
return taskPersistenceMapper.toDomain(savedTaskEntity);
2430
}
31+
32+
@Override
33+
public Optional<Task> findById(Long id) {
34+
Optional<TaskEntity> taskEntity = taskRepository.findById(id);
35+
return taskEntity.map(taskPersistenceMapper::toDomain);
36+
}
37+
38+
@Override
39+
public Page<FindTaskListResponse> findAllByRequesterId(Long requesterId, Pageable pageable, FindTaskListRequest findTaskListRequest) {
40+
Page<TaskEntity> taskList = taskRepository.findRequestedTaskList(requesterId, pageable, findTaskListRequest);
41+
return taskList.map(this::convertToFindTaskListResponse);
42+
}
43+
44+
private FindTaskListResponse convertToFindTaskListResponse(TaskEntity taskEntity) {
45+
return new FindTaskListResponse(
46+
taskEntity.getTaskId(),
47+
taskEntity.getTaskCode(),
48+
taskEntity.getCreatedAt(),
49+
taskEntity.getCategory().getMainCategory().getName(),
50+
taskEntity.getCategory().getName(),
51+
taskEntity.getTitle(),
52+
taskEntity.getProcessor() != null ? taskEntity.getProcessor().getName() : null,
53+
taskEntity.getStatus().getStatusName(),
54+
taskEntity.getCompletedAt()
55+
);
56+
}
2557
}

src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/TaskStatus.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package clap.server.adapter.outbound.persistense.entity.task.constant;
22

3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
35
import lombok.Getter;
46
import lombok.RequiredArgsConstructor;
57

@@ -13,4 +15,18 @@ public enum TaskStatus {
1315
TERMINATED("종료");
1416

1517
private final String description;
18+
19+
@JsonValue
20+
public String getDescription() {
21+
return description;
22+
}
23+
@JsonCreator
24+
public static TaskStatus fromDescription(String description) {
25+
for (TaskStatus status : TaskStatus.values()) {
26+
if (status.getDescription().equals(description)) {
27+
return status;
28+
}
29+
}
30+
throw new IllegalArgumentException("Unknown description: " + description);
31+
}
1632
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package clap.server.adapter.outbound.persistense.repository.task;
2+
3+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
4+
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
5+
import org.springframework.data.domain.Page;
6+
import org.springframework.data.domain.Pageable;
7+
8+
public interface TaskCustomRepository {
9+
10+
Page<TaskEntity> findRequestedTaskList(Long requesterId, Pageable pageable, FindTaskListRequest findTaskListRequest);
11+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package clap.server.adapter.outbound.persistense.repository.task;
2+
3+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
4+
import clap.server.adapter.outbound.persistense.entity.task.QTaskEntity;
5+
import clap.server.adapter.outbound.persistense.entity.task.TaskEntity;
6+
import com.querydsl.core.BooleanBuilder;
7+
import com.querydsl.jpa.impl.JPAQueryFactory;
8+
import lombok.RequiredArgsConstructor;
9+
import org.springframework.data.domain.Page;
10+
import org.springframework.data.domain.PageImpl;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.stereotype.Repository;
13+
14+
import java.time.LocalDateTime;
15+
import java.util.List;
16+
17+
@Repository
18+
@RequiredArgsConstructor
19+
public class TaskCustomRepositoryImpl implements TaskCustomRepository {
20+
21+
private final JPAQueryFactory queryFactory;
22+
23+
@Override
24+
public Page<TaskEntity> findRequestedTaskList(Long requesterId, Pageable pageable, FindTaskListRequest findTaskListRequest) {
25+
QTaskEntity task = QTaskEntity.taskEntity;
26+
BooleanBuilder whereClause = new BooleanBuilder();
27+
whereClause.and(task.requester.memberId.eq(requesterId));
28+
29+
Long categoryId = findTaskListRequest.categoryId();
30+
Long mainCategoryId = findTaskListRequest.mainCategoryId();
31+
String title = findTaskListRequest.title();
32+
String nickName = findTaskListRequest.nickName();
33+
Long statusId = findTaskListRequest.statusId();
34+
Integer term = findTaskListRequest.term();
35+
36+
if (term != null) {
37+
LocalDateTime fromDate = LocalDateTime.now().minusMonths(term);
38+
whereClause.and(task.createdAt.after(fromDate));
39+
}
40+
if (categoryId != null) {
41+
whereClause.and(task.category.categoryId.eq(categoryId));
42+
}
43+
if (mainCategoryId != null) {
44+
whereClause.and(task.category.mainCategory.categoryId.eq(mainCategoryId));
45+
}
46+
if (title != null && !title.isEmpty()) {
47+
whereClause.and(task.title.containsIgnoreCase(title));
48+
}
49+
if (nickName != null) {
50+
whereClause.and(task.processor.nickname.eq(nickName));
51+
}
52+
if (statusId != null) {
53+
whereClause.and(task.status.statusId.eq(statusId));
54+
}
55+
56+
List<TaskEntity> result = queryFactory
57+
.selectFrom(task)
58+
.where(whereClause)
59+
.offset(pageable.getOffset())
60+
.limit(pageable.getPageSize())
61+
.fetch();
62+
63+
int total = queryFactory
64+
.selectFrom(task)
65+
.where(whereClause)
66+
.fetch().size();
67+
68+
return new PageImpl<>(result, pageable, total);
69+
}
70+
}

src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
import org.springframework.stereotype.Repository;
66

77
@Repository
8-
public interface TaskRepository extends JpaRepository<TaskEntity, Long> {
8+
public interface TaskRepository extends JpaRepository<TaskEntity, Long>, TaskCustomRepository {
99
}

src/main/java/clap/server/application/TaskService.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import clap.server.adapter.inbound.web.dto.task.CreateTaskRequest;
44
import clap.server.adapter.inbound.web.dto.task.CreateTaskResponse;
5+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
6+
import clap.server.adapter.inbound.web.dto.task.FindTaskListResponse;
57
import clap.server.adapter.outbound.persistense.entity.task.StatusEntity;
68
import clap.server.adapter.outbound.persistense.mapper.StatusPersistenceMapper;
79
import clap.server.adapter.outbound.persistense.repository.task.StatusRepository;
@@ -11,12 +13,15 @@
1113
import clap.server.application.port.inbound.task.TaskUsecase;
1214
import clap.server.application.port.outbound.task.CommandAttachmentPort;
1315
import clap.server.application.port.outbound.task.CommandTaskPort;
16+
import clap.server.application.port.outbound.task.LoadTaskPort;
1417
import clap.server.common.annotation.architecture.ApplicationService;
1518
import clap.server.domain.model.member.Member;
1619
import clap.server.domain.model.task.Attachment;
1720
import clap.server.domain.model.task.Category;
1821
import clap.server.domain.model.task.Task;
1922
import lombok.RequiredArgsConstructor;
23+
import org.springframework.data.domain.Page;
24+
import org.springframework.data.domain.Pageable;
2025
import org.springframework.transaction.annotation.Transactional;
2126

2227
import java.util.List;
@@ -35,6 +40,7 @@ public class TaskService implements TaskUsecase {
3540
private final CommandAttachmentPort commandAttachmentPort;
3641
private final StatusRepository statusRepository; //TODO: 계층화
3742
private final StatusPersistenceMapper statusPersistenceMapper;
43+
private final LoadTaskPort loadTaskPort;
3844

3945
@Override
4046
@Transactional
@@ -52,4 +58,11 @@ public CreateTaskResponse createTask(Long requesterId, CreateTaskRequest createT
5258

5359
return toCreateTaskResponse(savedTask);
5460
}
61+
62+
63+
@Override
64+
public Page<FindTaskListResponse> findRequestedTaskList(Long requesterId, Pageable pageable, FindTaskListRequest findTaskListRequest) {
65+
Member requester = memberService.findActiveMember(requesterId);
66+
return loadTaskPort.findAllByRequesterId(requester.getMemberId(), pageable, findTaskListRequest);
67+
}
5568
}

src/main/java/clap/server/application/port/inbound/task/TaskUsecase.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
import clap.server.adapter.inbound.web.dto.task.CreateTaskRequest;
44
import clap.server.adapter.inbound.web.dto.task.CreateTaskResponse;
5+
import clap.server.adapter.inbound.web.dto.task.FindTaskListRequest;
6+
import clap.server.adapter.inbound.web.dto.task.FindTaskListResponse;
7+
import org.springframework.data.domain.Page;
8+
import org.springframework.data.domain.Pageable;
59

610
public interface TaskUsecase {
711
CreateTaskResponse createTask(Long memberId, CreateTaskRequest createTaskRequest);
12+
13+
Page<FindTaskListResponse> findRequestedTaskList(Long memberId, Pageable pageable, FindTaskListRequest findTaskListRequest);
814
}

0 commit comments

Comments
 (0)