From b3ed0101f1505af1fa11933965c3feae80260ff5 Mon Sep 17 00:00:00 2001 From: bbbbooo Date: Mon, 23 Dec 2024 16:32:34 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat=20:=20=EB=AA=A9=ED=91=9C=EB=B3=84=20?= =?UTF-8?q?=ED=95=A0=EC=9D=BC=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C,=20?= =?UTF-8?q?=EB=AA=A9=ED=91=9C=20=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=AC=B4=ED=95=9C=EC=8A=A4=ED=81=AC=EB=A1=A4=20=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../todo/repository/GoalRepository.java | 6 +++ .../todo/repository/TodoRepository.java | 5 ++- .../codeit/todo/service/todo/TodoService.java | 7 +--- .../service/todo/impl/TodoServiceImpl.java | 42 +++++++++++++------ .../todo/web/controller/TodoController.java | 9 ++-- .../ReadDashBoardTodoWithGoalRequest.java | 10 +++++ 6 files changed, 54 insertions(+), 25 deletions(-) create mode 100644 src/main/java/com/codeit/todo/web/dto/request/todo/ReadDashBoardTodoWithGoalRequest.java diff --git a/src/main/java/com/codeit/todo/repository/GoalRepository.java b/src/main/java/com/codeit/todo/repository/GoalRepository.java index 2bdc7ef..ddd6415 100644 --- a/src/main/java/com/codeit/todo/repository/GoalRepository.java +++ b/src/main/java/com/codeit/todo/repository/GoalRepository.java @@ -1,6 +1,8 @@ package com.codeit.todo.repository; import com.codeit.todo.domain.Goal; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; @@ -10,4 +12,8 @@ public interface GoalRepository extends JpaRepository { List findByUser_UserId(int userId); Optional findByGoalIdAndUser_UserId(int goalId, int userId); + + Slice findByUser_UserId(int userId, Pageable pageable); + + Slice findByGoalIdAndUser_UserId(Integer goalId, int userId, Pageable pageable); } diff --git a/src/main/java/com/codeit/todo/repository/TodoRepository.java b/src/main/java/com/codeit/todo/repository/TodoRepository.java index 45682f7..9fc7177 100644 --- a/src/main/java/com/codeit/todo/repository/TodoRepository.java +++ b/src/main/java/com/codeit/todo/repository/TodoRepository.java @@ -20,5 +20,8 @@ public interface TodoRepository extends JpaRepository { Slice findByGoal_GoalIdAndTodoIdLessThanOrderByTodoIdDesc(int goalId, Integer lastTodoId, Pageable pageable); @Query("select t from Todo t where t.goal.goalId in :goalIds and :today between t.startDate and t.endDate") - List findTodosBetweenDates(@Param("goalIds") List goalIds, @Param("today") LocalDate today); + List findTodosByGoalIdsBetweenDates(@Param("goalIds") List goalIds, @Param("today") LocalDate today); + + @Query("select t from Todo t where t.goal.goalId = :goalId and :today between t.startDate and t.endDate") + List findTodosByGoalIdBetweenDates(@Param("goalId") int goalId, @Param("today") LocalDate today); } diff --git a/src/main/java/com/codeit/todo/service/todo/TodoService.java b/src/main/java/com/codeit/todo/service/todo/TodoService.java index 94d8e84..a24d730 100644 --- a/src/main/java/com/codeit/todo/service/todo/TodoService.java +++ b/src/main/java/com/codeit/todo/service/todo/TodoService.java @@ -1,9 +1,6 @@ package com.codeit.todo.service.todo; -import com.codeit.todo.web.dto.request.todo.CreateTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest; -import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest; +import com.codeit.todo.web.dto.request.todo.*; import com.codeit.todo.web.dto.response.todo.*; import org.springframework.data.domain.Slice; @@ -15,7 +12,7 @@ public interface TodoService { CreateTodoResponse saveTodo(int userId, CreateTodoRequest request); - List findTodoListWithGoals(int userId, ReadTodoWithGoalRequest request); + Slice findTodoListWithGoals(int userId, ReadDashBoardTodoWithGoalRequest request); Slice findTodoListWithGoal(int userId, int goalId, ReadTodoWithGoalRequest request); diff --git a/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java b/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java index 4a17ae3..3af4acc 100644 --- a/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java +++ b/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java @@ -11,12 +11,10 @@ import com.codeit.todo.repository.TodoRepository; import com.codeit.todo.service.storage.StorageService; import com.codeit.todo.service.todo.TodoService; -import com.codeit.todo.web.dto.request.todo.CreateTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest; -import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest; +import com.codeit.todo.web.dto.request.todo.*; import com.codeit.todo.web.dto.response.complete.ReadCompleteResponse; import com.codeit.todo.web.dto.response.todo.*; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.PageRequest; @@ -108,19 +106,37 @@ public CreateTodoResponse saveTodo(int userId, CreateTodoRequest request) { @Transactional(readOnly = true) @Override - public List findTodoListWithGoals(int userId, ReadTodoWithGoalRequest request) { - List goals = goalRepository.findByUser_UserId(userId); + public Slice findTodoListWithGoals(int userId, @Valid ReadDashBoardTodoWithGoalRequest request) { + int pageSize = request.size(); + Pageable pageable = PageRequest.of(0, pageSize); + + Slice goals; + if (Objects.isNull(request.lastGoalId()) || request.lastGoalId() <= 0) { + goals = goalRepository.findByUser_UserId(userId, pageable); + } else { + goals = goalRepository.findByGoalIdAndUser_UserId(request.lastGoalId(), userId, pageable); + } - return goals.stream() + List responses = goals.getContent().stream() .map(goal -> { - Pageable pageable = PageRequest.of(0, request.size()); - Slice todos = todoRepository.findByGoal_GoalIdOrderByTodoIdDesc(goal.getGoalId(), pageable); + List todos = todoRepository.findTodosByGoalIdBetweenDates(goal.getGoalId(), LocalDate.now()); - List responses = getTodoResponses(todos); + List todosResponses = todos.stream() + .map(todo -> { + List completes = completeRepository.findByTodo_TodoId(todo.getTodoId()); - return ReadTodosWithGoalsResponse.from(goal, responses); + List completeResponses = completes.stream() + .map(ReadCompleteResponse::from) + .toList(); - }).toList(); + return ReadTodosResponse.from(todo, completeResponses); + }).toList(); + + return ReadTodosWithGoalsResponse.from(goal, todosResponses); + }) + .toList(); + + return new SliceImpl<>(responses, pageable, goals.hasNext()); } @Transactional(readOnly = true) @@ -234,7 +250,7 @@ private List getTodayTodos(LocalDate today, int userId) { .map(Goal::getGoalId) .toList(); - return todoRepository.findTodosBetweenDates(goalIds, today); + return todoRepository.findTodosByGoalIdsBetweenDates(goalIds, today); } private List getTodoResponses(Slice todos) { diff --git a/src/main/java/com/codeit/todo/web/controller/TodoController.java b/src/main/java/com/codeit/todo/web/controller/TodoController.java index c410cf6..7839d5a 100644 --- a/src/main/java/com/codeit/todo/web/controller/TodoController.java +++ b/src/main/java/com/codeit/todo/web/controller/TodoController.java @@ -2,10 +2,7 @@ import com.codeit.todo.repository.CustomUserDetails; import com.codeit.todo.service.todo.TodoService; -import com.codeit.todo.web.dto.request.todo.CreateTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoRequest; -import com.codeit.todo.web.dto.request.todo.ReadTodoWithGoalRequest; -import com.codeit.todo.web.dto.request.todo.UpdateTodoRequest; +import com.codeit.todo.web.dto.request.todo.*; import com.codeit.todo.web.dto.response.Response; import com.codeit.todo.web.dto.response.goal.ReadGoalsResponse; import com.codeit.todo.web.dto.response.todo.*; @@ -51,8 +48,8 @@ public Response> getTodoList( @ApiResponse(responseCode = "200", description = "조회 성공") }) @GetMapping("/goals") - public Response> getTodoWithGoalList( - @Valid @ModelAttribute ReadTodoWithGoalRequest request, + public Response> getTodoWithGoalList( + @Valid @ModelAttribute ReadDashBoardTodoWithGoalRequest request, @AuthenticationPrincipal CustomUserDetails userDetails ) { int userId = userDetails.getUserId(); diff --git a/src/main/java/com/codeit/todo/web/dto/request/todo/ReadDashBoardTodoWithGoalRequest.java b/src/main/java/com/codeit/todo/web/dto/request/todo/ReadDashBoardTodoWithGoalRequest.java new file mode 100644 index 0000000..487bcc0 --- /dev/null +++ b/src/main/java/com/codeit/todo/web/dto/request/todo/ReadDashBoardTodoWithGoalRequest.java @@ -0,0 +1,10 @@ +package com.codeit.todo.web.dto.request.todo; + +import jakarta.validation.constraints.Min; + +public record ReadDashBoardTodoWithGoalRequest( + Integer lastGoalId, + @Min(3) + int size +) { +} From d94b4ec7b7a59dd52dc4664556e932730781adbb Mon Sep 17 00:00:00 2001 From: bbbbooo Date: Mon, 23 Dec 2024 16:49:34 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat=20:=20=EC=A7=84=ED=96=89=EC=83=81?= =?UTF-8?q?=ED=99=A9=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/todo/impl/TodoServiceImpl.java | 19 ++++++++++++++++++- .../todo/ReadTodosWithGoalsResponse.java | 4 +++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java b/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java index 3af4acc..007644e 100644 --- a/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java +++ b/src/main/java/com/codeit/todo/service/todo/impl/TodoServiceImpl.java @@ -132,7 +132,9 @@ public Slice findTodoListWithGoals(int userId, @Vali return ReadTodosResponse.from(todo, completeResponses); }).toList(); - return ReadTodosWithGoalsResponse.from(goal, todosResponses); + double goalProgress = calculateGoalProgress(todos); + + return ReadTodosWithGoalsResponse.from(goal, todosResponses, goalProgress); }) .toList(); @@ -265,4 +267,19 @@ private List getTodoResponses(Slice todos) { return ReadTodosResponse.from(todo, completeResponses); }).toList(); } + + private double calculateGoalProgress(List todos) { + long totalCompletes = 0; + long completedCompletes = 0; + + for (Todo todo : todos) { + List completes = completeRepository.findByTodo_TodoId(todo.getTodoId()); + totalCompletes += completes.size(); + completedCompletes += completes.stream() + .filter(complete -> COMPLETE.equals(complete.getCompleteStatus())) + .count(); + } + + return totalCompletes > 0 ? (completedCompletes / (double) totalCompletes) * 100 : 0; + } } diff --git a/src/main/java/com/codeit/todo/web/dto/response/todo/ReadTodosWithGoalsResponse.java b/src/main/java/com/codeit/todo/web/dto/response/todo/ReadTodosWithGoalsResponse.java index 90ca0fa..15728da 100644 --- a/src/main/java/com/codeit/todo/web/dto/response/todo/ReadTodosWithGoalsResponse.java +++ b/src/main/java/com/codeit/todo/web/dto/response/todo/ReadTodosWithGoalsResponse.java @@ -10,13 +10,15 @@ public record ReadTodosWithGoalsResponse( int goalId, String goalTitle, String goalColor, + double progress, List todos ) { - public static ReadTodosWithGoalsResponse from(Goal goal, List responses) { + public static ReadTodosWithGoalsResponse from(Goal goal, List responses, double goalProgress) { return ReadTodosWithGoalsResponse.builder() .goalId(goal.getGoalId()) .goalTitle(goal.getGoalTitle()) .goalColor(goal.getColor()) + .progress(goalProgress) .todos(responses) .build(); } From 7731eafdab534e921ea7161caf368879e6e76360 Mon Sep 17 00:00:00 2001 From: bbbbooo Date: Mon, 23 Dec 2024 16:54:24 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix=20:=20jar=20=ED=8C=8C=EC=9D=BC=EC=9D=B4?= =?UTF-8?q?=20=EC=97=85=EB=A1=9C=EB=93=9C=EB=90=98=EB=8A=94=20=EC=8B=9C?= =?UTF-8?q?=EC=A0=90=EC=9D=84=20=EB=A8=B8=EC=A7=80=ED=95=A0=EB=95=8C?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/cd.yml | 20 ++++++++++++++++++++ .github/workflows/ci.yml | 16 +--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index efba31b..78edcb7 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -13,6 +13,15 @@ jobs: - name: Checkout repository uses: actions/checkout@v2 + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'temurin' + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 + - name: Add SSH host key run: | mkdir -p ~/.ssh @@ -24,6 +33,17 @@ jobs: echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem chmod 600 ~/.ssh/private_key.pem + - name: Build with Gradle + run: ./gradlew build -x test + + - name: Upload JAR to Remote Server + run: | + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem + chmod 600 ~/.ssh/private_key.pem + scp -i ~/.ssh/private_key.pem build/libs/todo-0.0.1-SNAPSHOT.jar ${{ secrets.USER }}@${{ secrets.HOST }}:${{ secrets.APP_DIR }} + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Deploy to Remote Server run: | ssh -i ~/.ssh/private_key.pem ${{ secrets.USER }}@${{ secrets.HOST }} ' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4189900..5208407 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,18 +26,4 @@ jobs: run: ./gradlew test - name: Build with Gradle - run: ./gradlew build -x test - - - name: Add SSH host key - run: | - mkdir -p ~/.ssh - ssh-keyscan -H ${{ secrets.HOST }} >> ~/.ssh/known_hosts - chmod 644 ~/.ssh/known_hosts - - - name: Upload JAR to Remote Server - run: | - echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/private_key.pem - chmod 600 ~/.ssh/private_key.pem - scp -i ~/.ssh/private_key.pem build/libs/todo-0.0.1-SNAPSHOT.jar ${{ secrets.USER }}@${{ secrets.HOST }}:${{ secrets.APP_DIR }} - env: - SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} \ No newline at end of file + run: ./gradlew build -x test \ No newline at end of file