diff --git a/linkmind/src/main/java/com/app/toaster/infrastructure/ToastRepository.java b/linkmind/src/main/java/com/app/toaster/infrastructure/ToastRepository.java index 5c019d22..5327aaaa 100644 --- a/linkmind/src/main/java/com/app/toaster/infrastructure/ToastRepository.java +++ b/linkmind/src/main/java/com/app/toaster/infrastructure/ToastRepository.java @@ -1,14 +1,15 @@ package com.app.toaster.infrastructure; - import com.app.toaster.domain.Category; import com.app.toaster.domain.User; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import com.app.toaster.domain.Category; import com.app.toaster.domain.Toast; import com.app.toaster.domain.User; + import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -18,40 +19,46 @@ import java.util.List; public interface ToastRepository extends JpaRepository { - ArrayList getAllByCategory(Category category); - ArrayList findByIsReadAndCategory(Boolean isRead, Category category); + ArrayList getAllByCategory(Category category); + + ArrayList findByIsReadAndCategory(Boolean isRead, Category category); + + ArrayList getAllByUser(User user); + + ArrayList getAllByUserAndIsReadIsTrue(User user); + + @Modifying + @Query("UPDATE Toast t SET t.category = null WHERE t.category.categoryId IN :categoryIds") + void updateCategoryIdsToNull(@Param("categoryIds") List categoryIds); - ArrayList getAllByUser(User user); + @Query("SELECT t FROM Toast t WHERE " + + "t.user.userId = :userId and " + + "t.title LIKE CONCAT('%',:query, '%')" + ) + List searchToastsByQuery(Long userId, String query); - ArrayList getAllByUserAndIsReadIsTrue(User user); + Long countAllByUser(User user); - @Modifying - @Query("UPDATE Toast t SET t.category = null WHERE t.category.categoryId IN :categoryIds") - void updateCategoryIdsToNull(@Param("categoryIds") List categoryIds); + Long countALLByUserAndIsReadTrue(User user); - @Query("SELECT t FROM Toast t WHERE " + - "t.user.userId = :userId and " + - "t.title LIKE CONCAT('%',:query, '%')" - ) - List searchToastsByQuery(Long userId, String query); + Long countALLByUserAndIsReadFalse(User user); - Long countAllByUser(User user); + Long countAllByCategory(Category category); - Long countAllByCategory(Category category); + Long countAllByCategoryAndIsReadTrue(Category category); - Long countALLByUserAndIsReadTrue(User user); + Long countAllByCategoryAndIsReadFalse(Category category); - Long countAllByUserAndIsReadFalse(User user); + @Query("SELECT COUNT(t) FROM Toast t WHERE t.user.userId = :userId AND t.isRead = false") + Integer getUnReadToastNumber(Long userId); - @Query("SELECT COUNT(t) FROM Toast t WHERE t.user.userId = :userId AND t.isRead = false") - Integer getUnReadToastNumber(Long userId); - @Query("SELECT COUNT(t) FROM Toast t WHERE t.user=:user AND t.createdAt >= :startOfWeek AND t.createdAt <= :endOfWeek") - Long countAllByCreatedAtThisWeek(@Param("startOfWeek") LocalDateTime startOfWeek, + @Query("SELECT COUNT(t) FROM Toast t WHERE t.user=:user AND t.createdAt >= :startOfWeek AND t.createdAt <= :endOfWeek") + Long countAllByCreatedAtThisWeek(@Param("startOfWeek") LocalDateTime startOfWeek, @Param("endOfWeek") LocalDateTime endOfWeek, @Param("user") User user); - @Query("SELECT COUNT(t) FROM Toast t WHERE t.user=:user AND t.isRead = true AND t.updateAt >= :startOfWeek AND t.updateAt <= :endOfWeek") - Long countAllByUpdateAtThisWeek(@Param("startOfWeek") LocalDateTime startOfWeek, + @Query("SELECT COUNT(t) FROM Toast t WHERE t.user=:user AND t.isRead = true AND t.updateAt >= :startOfWeek AND t.updateAt <= :endOfWeek") + Long countAllByUpdateAtThisWeek(@Param("startOfWeek") LocalDateTime startOfWeek, @Param("endOfWeek") LocalDateTime endOfWeek, @Param("user") User user); diff --git a/linkmind/src/main/java/com/app/toaster/service/category/CategoryService.java b/linkmind/src/main/java/com/app/toaster/service/category/CategoryService.java index 6b18c4fe..9c7cef77 100644 --- a/linkmind/src/main/java/com/app/toaster/service/category/CategoryService.java +++ b/linkmind/src/main/java/com/app/toaster/service/category/CategoryService.java @@ -19,8 +19,10 @@ import com.app.toaster.infrastructure.TimerRepository; import com.app.toaster.infrastructure.ToastRepository; import com.app.toaster.infrastructure.UserRepository; + import lombok.RequiredArgsConstructor; import lombok.val; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,146 +35,166 @@ @Service @RequiredArgsConstructor public class CategoryService { - private final UserRepository userRepository; - private final CategoryRepository categoryRepository; - private final ToastRepository toastRepository; - - private final static int MAX_CATERGORY_NUMBER = 15; - private final TimerRepository timerRepository; - - @Transactional - public void createCategory(final Long userId, final CreateCategoryDto createCategoryDto){ - User presentUser = findUser(userId); - - // 현재 유저의 최대 우선순위를 가져와서 새로운 우선순위를 설정 - val maxPriority = categoryRepository.findMaxPriorityByUser(presentUser); - - val categoryNum= categoryRepository.countAllByUser(presentUser); - System.out.println(categoryNum); - - if(categoryNum >= MAX_CATERGORY_NUMBER){ - throw new CustomException(Error.BAD_REQUEST_CREATE_CLIP_EXCEPTION, Error.BAD_REQUEST_CREATE_CLIP_EXCEPTION.getMessage()); - } - - //카테고리 생성 - Category newCategory = Category.builder() - .title(createCategoryDto.categoryTitle()) - .user(presentUser) - .priority(maxPriority + 1) - .build(); - - categoryRepository.save(newCategory); - } - - @Transactional - public void deleteCategory(final ArrayList deleteCategoryDto){ - if(deleteCategoryDto.isEmpty()){ - throw new BadRequestException(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage()); - } - - toastRepository.updateCategoryIdsToNull(deleteCategoryDto); - - for (Long categoryId : deleteCategoryDto) { - Category category = categoryRepository.findById(categoryId) - .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); - - categoryRepository.decreasePriorityNextDeleteCategory(categoryId, category.getPriority(),category.getUser().getUserId()); - - Reminder timer = timerRepository.findByCategory_CategoryId(categoryId); - if(timer != null) - timerRepository.delete(timer); - categoryRepository.delete(category); - } - - } - - public CategoriesResponse getCategories(final Long userId){ - User presentUser = findUser(userId); - - return CategoriesResponse.of(toastRepository.countAllByUser(presentUser),categoryRepository.findAllByUserOrderByPriority(presentUser) - .stream() - .map(category -> CategoryResponse.builder() - .categoryId(category.getCategoryId()) - .categoryTitle(category.getTitle()) - .toastNum(toastRepository.getAllByCategory(category).size()).build() - ).collect(Collectors.toList())); - - - } - - public GetCategoryResponseDto getCategory(final Long userId, final Long categoryId, final ToastFilter filter) { - User presentUser = findUser(userId); - if (categoryId ==0){ - List toastAllList = toastRepository.getAllByUser(presentUser); - List toastListDto = mapToToastDtoList(toastAllList, filter, null); - return GetCategoryResponseDto.builder() - .allToastNum(toastAllList.size()) - .toastListDto(toastListDto) - .build(); - } - - Category category = categoryRepository.findById(categoryId) - .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); - - category.updateLatestReadTime(LocalDateTime.now()); - - ArrayList toasts = toastRepository.getAllByCategory(category); - List toastListDto = mapToToastDtoList(toasts, filter, category); - - return GetCategoryResponseDto.builder() - .allToastNum(toasts.size()) - .toastListDto(toastListDto) - .build(); - } - - //순서 업데이트 - @Transactional - public void editCategoryPriority(ChangeCateoryPriorityDto changeCateoryPriorityDto){ - - val newPriority = changeCateoryPriorityDto.newPriority(); - - Category category = categoryRepository.findById(changeCateoryPriorityDto.categoryId()) - .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); - - int currentPriority = category.getPriority(); - category.updateCategoryPriority(changeCateoryPriorityDto.newPriority()); - - if(currentPriority < newPriority) - categoryRepository.decreasePriorityByOne(changeCateoryPriorityDto.categoryId(), currentPriority, newPriority, category.getUser().getUserId()); - else if (currentPriority > newPriority) - categoryRepository.increasePriorityByOne(changeCateoryPriorityDto.categoryId(), currentPriority, newPriority,category.getUser().getUserId()); - - - } - - @Transactional - public void editCategoryTitle(ChangeCateoryTitleDto changeCateoryTitleDto){ - - categoryRepository.updateCategoryTitle(changeCateoryTitleDto.categoryId(), changeCateoryTitleDto.newTitle()); - } - - //해당 유저 탐색 - private User findUser(Long userId){ - return userRepository.findByUserId(userId).orElseThrow( - ()-> new NotFoundException(Error.NOT_FOUND_USER_EXCEPTION, Error.NOT_FOUND_USER_EXCEPTION.getMessage()) - ); - } - - private List mapToToastDtoList(List toasts, ToastFilter filter, Category category) { - Stream toastStream = switch (filter) { - case ALL -> toasts.stream(); - case READ -> toasts.stream().filter(Toast::getIsRead); - case UNREAD ->toasts.stream().filter(toast -> !toast.getIsRead()); - default -> - throw new NotFoundException(Error.NOT_FOUND_TOAST_FILTER, Error.NOT_FOUND_TOAST_FILTER.getMessage()); + private final UserRepository userRepository; + private final CategoryRepository categoryRepository; + private final ToastRepository toastRepository; + + private final static int MAX_CATERGORY_NUMBER = 15; + private final TimerRepository timerRepository; + + @Transactional + public void createCategory(final Long userId, final CreateCategoryDto createCategoryDto) { + User presentUser = findUser(userId); + + // 현재 유저의 최대 우선순위를 가져와서 새로운 우선순위를 설정 + val maxPriority = categoryRepository.findMaxPriorityByUser(presentUser); + + val categoryNum = categoryRepository.countAllByUser(presentUser); + System.out.println(categoryNum); + + if (categoryNum >= MAX_CATERGORY_NUMBER) { + throw new CustomException(Error.BAD_REQUEST_CREATE_CLIP_EXCEPTION, + Error.BAD_REQUEST_CREATE_CLIP_EXCEPTION.getMessage()); + } + + //카테고리 생성 + Category newCategory = Category.builder() + .title(createCategoryDto.categoryTitle()) + .user(presentUser) + .priority(maxPriority + 1) + .build(); + + categoryRepository.save(newCategory); + } + + @Transactional + public void deleteCategory(final ArrayList deleteCategoryDto) { + if (deleteCategoryDto.isEmpty()) { + throw new BadRequestException(Error.BAD_REQUEST_VALIDATION, Error.BAD_REQUEST_VALIDATION.getMessage()); + } + + toastRepository.updateCategoryIdsToNull(deleteCategoryDto); + + for (Long categoryId : deleteCategoryDto) { + Category category = categoryRepository.findById(categoryId) + .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, + Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); + + categoryRepository.decreasePriorityNextDeleteCategory(categoryId, category.getPriority(), + category.getUser().getUserId()); + + Reminder timer = timerRepository.findByCategory_CategoryId(categoryId); + if (timer != null) + timerRepository.delete(timer); + categoryRepository.delete(category); + } + + } + + public CategoriesResponse getCategories(final Long userId) { + User presentUser = findUser(userId); + + return CategoriesResponse.of(toastRepository.countAllByUser(presentUser), + categoryRepository.findAllByUserOrderByPriority(presentUser) + .stream() + .map(category -> CategoryResponse.builder() + .categoryId(category.getCategoryId()) + .categoryTitle(category.getTitle()) + .toastNum(toastRepository.getAllByCategory(category).size()).build() + ).collect(Collectors.toList())); + + } + + public GetCategoryResponseDto getCategory(final Long userId, final Long categoryId, final ToastFilter filter) { + User presentUser = findUser(userId); + if (categoryId == 0) { + List toastAllList = toastRepository.getAllByUser(presentUser); + List toastListDto = mapToToastDtoList(toastAllList, filter, null); + return GetCategoryResponseDto.builder() + .allToastNum(countToToast(filter,null,presentUser,true)) + .toastListDto(toastListDto) + .build(); + } + + Category category = categoryRepository.findById(categoryId) + .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, + Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); + + category.updateLatestReadTime(LocalDateTime.now()); + + ArrayList toasts = toastRepository.getAllByCategory(category); + List toastListDto = mapToToastDtoList(toasts, filter, category); + + return GetCategoryResponseDto.builder() + .allToastNum(countToToast(filter,category,presentUser,false)) + .toastListDto(toastListDto) + .build(); + } + + //순서 업데이트 + @Transactional + public void editCategoryPriority(ChangeCateoryPriorityDto changeCateoryPriorityDto) { + + val newPriority = changeCateoryPriorityDto.newPriority(); + + Category category = categoryRepository.findById(changeCateoryPriorityDto.categoryId()) + .orElseThrow(() -> new NotFoundException(Error.NOT_FOUND_CATEGORY_EXCEPTION, + Error.NOT_FOUND_CATEGORY_EXCEPTION.getMessage())); + + int currentPriority = category.getPriority(); + category.updateCategoryPriority(changeCateoryPriorityDto.newPriority()); + + if (currentPriority < newPriority) + categoryRepository.decreasePriorityByOne(changeCateoryPriorityDto.categoryId(), currentPriority, + newPriority, category.getUser().getUserId()); + else if (currentPriority > newPriority) + categoryRepository.increasePriorityByOne(changeCateoryPriorityDto.categoryId(), currentPriority, + newPriority, category.getUser().getUserId()); + + } + + @Transactional + public void editCategoryTitle(ChangeCateoryTitleDto changeCateoryTitleDto) { + + categoryRepository.updateCategoryTitle(changeCateoryTitleDto.categoryId(), changeCateoryTitleDto.newTitle()); + } + + //해당 유저 탐색 + private User findUser(Long userId) { + return userRepository.findByUserId(userId).orElseThrow( + () -> new NotFoundException(Error.NOT_FOUND_USER_EXCEPTION, Error.NOT_FOUND_USER_EXCEPTION.getMessage()) + ); + } + + public DuplicatedResponse checkDuplicatedTitle(Long userId, String title) { + return DuplicatedResponse.of(categoryRepository.existsCategoriesByUserAndTitle(findUser(userId), title)); + + } + + private List mapToToastDtoList(List toasts, ToastFilter filter, Category category) { + Stream toastStream = switch (filter) { + case ALL -> toasts.stream(); + case READ -> toasts.stream().filter(Toast::getIsRead); + case UNREAD -> toasts.stream().filter(toast -> !toast.getIsRead()); + default -> + throw new NotFoundException(Error.NOT_FOUND_TOAST_FILTER, Error.NOT_FOUND_TOAST_FILTER.getMessage()); + }; + + return toastStream.map(ToastDto::of).toList(); + } + + private int countToToast(ToastFilter filter, Category category,User user, boolean isCategoryNull) { + if (!isCategoryNull) + return switch (filter) { + case ALL -> toastRepository.countAllByCategory(category).intValue(); + case READ -> toastRepository.countAllByCategoryAndIsReadTrue(category).intValue(); + case UNREAD -> toastRepository.countAllByCategoryAndIsReadFalse(category).intValue(); + }; + return switch (filter){ + case ALL -> toastRepository.countAllByUser(user).intValue(); + case READ -> toastRepository.countALLByUserAndIsReadTrue(user).intValue(); + case UNREAD -> toastRepository.countALLByUserAndIsReadFalse(user).intValue(); }; - - return toastStream.map(ToastDto::of).toList(); - } - - public DuplicatedResponse checkDuplicatedTitle(Long userId, String title){ - return DuplicatedResponse.of(categoryRepository.existsCategoriesByUserAndTitle(findUser(userId), title)); - - } + } }