From 92414d74c83fa4f9a41139206fef9594215f17d2 Mon Sep 17 00:00:00 2001 From: Zakharov_Rostislav Date: Thu, 6 Jun 2024 21:35:41 +0400 Subject: [PATCH] mvc add searh and favorites table --- .../favorites/FavoriteRepository.java | 5 + .../controllers/users/UserBookController.java | 108 ++++++++++++++++++ .../controllers/users/UserService.java | 44 ++++--- .../main/resources/templates/book-search.html | 49 ++++++++ .../src/main/resources/templates/default.html | 8 ++ .../resources/templates/user-favorites.html | 49 ++++++++ 6 files changed, 248 insertions(+), 15 deletions(-) create mode 100644 SpringApp/library/src/main/java/com/ip/library/controllers/favorites/FavoriteRepository.java create mode 100644 SpringApp/library/src/main/java/com/ip/library/controllers/users/UserBookController.java create mode 100644 SpringApp/library/src/main/resources/templates/book-search.html create mode 100644 SpringApp/library/src/main/resources/templates/user-favorites.html diff --git a/SpringApp/library/src/main/java/com/ip/library/controllers/favorites/FavoriteRepository.java b/SpringApp/library/src/main/java/com/ip/library/controllers/favorites/FavoriteRepository.java new file mode 100644 index 0000000..11cc184 --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/controllers/favorites/FavoriteRepository.java @@ -0,0 +1,5 @@ +package com.ip.library.controllers.favorites; + +import org.springframework.data.repository.CrudRepository; + +public interface FavoriteRepository extends CrudRepository {} diff --git a/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserBookController.java b/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserBookController.java new file mode 100644 index 0000000..0a6291e --- /dev/null +++ b/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserBookController.java @@ -0,0 +1,108 @@ +package com.ip.library.controllers.users; + +import java.util.List; +import java.util.Map; + +import org.modelmapper.ModelMapper; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; + +import com.ip.library.controllers.authors.AuthorEntity; +import com.ip.library.controllers.books.BookDto; +import com.ip.library.controllers.books.BookEntity; +import com.ip.library.controllers.books.BookService; +import com.ip.library.core.api.PageAttributesMapper; +import com.ip.library.core.configuration.Constants; +import com.ip.library.core.security.UserPrincipal; + +@Controller +public class UserBookController { + private static final String BOOK_SEARCH_VIEW = "book-search"; + private static final String USER_FAVORITES_VIEW = "user-favorites"; + private static final String PAGE_ATTRIBUTE = "page"; + + private final UserService userService; + private final BookService bookService; + private final ModelMapper modelMapper; + + public UserBookController( + UserService userService, + BookService bookService, + ModelMapper modelMapper) { + this.bookService = bookService; + this.userService = userService; + this.modelMapper = modelMapper; + } + + private BookDto toBookDto (BookEntity entity) { + BookDto bookDto = modelMapper.map(entity, BookDto.class); + List authors = entity.getAuthorsBooks().stream().map(x -> x.getAuthor()).toList(); + bookDto.setAuthorsId(authors.stream().map(x -> x.getId()).toList()); + bookDto.setTypeName(entity.getType().getName()); + StringBuilder authorName = new StringBuilder(); + for (AuthorEntity authorEntity : authors) { + authorName.append(", ").append(authorEntity.getName()); + } + if (authorName.length() > 0) { + bookDto.setAuthorName(authorName.toString().substring(2)); + } else { + bookDto.setAuthorName("Неизвестен"); + } + return bookDto; + } + + @GetMapping + public String getFavorites( + @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, + Model model, + @AuthenticationPrincipal UserPrincipal principal) { + final Map attributes = PageAttributesMapper.toAttributes( + userService.getUserFavorities(principal.getId(), page, Constants.DEFUALT_PAGE_SIZE), + this::toBookDto); + model.addAllAttributes(attributes); + model.addAttribute(PAGE_ATTRIBUTE, page); + return USER_FAVORITES_VIEW; + } + + @PostMapping(Constants.API_URL + "/removeFavorite/{id}") + public String removeFavorite( + @PathVariable(name = "id") Long id, + @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, + RedirectAttributes redirectAttributes, + @AuthenticationPrincipal UserPrincipal principal) { + redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page); + userService.removeFavorite(principal.getId(), id); + return Constants.REDIRECT_VIEW + "/"; + } + + @GetMapping(Constants.API_URL + "/search") + public String getAll( + @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, + @RequestParam(name = "typeId", defaultValue = "-1") Long typeId, + @RequestParam(name = "authorId", defaultValue = "-1") Long authorId, + Model model) { + final Map attributes = PageAttributesMapper.toAttributes( + bookService.getAll(typeId, authorId, page, Constants.DEFUALT_PAGE_SIZE), + this::toBookDto); + model.addAllAttributes(attributes); + model.addAttribute(PAGE_ATTRIBUTE, page); + return BOOK_SEARCH_VIEW; + } + + @PostMapping(Constants.API_URL + "/addFavorite/{id}") + public String addFavorite( + @PathVariable(name = "id") Long id, + @RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page, + RedirectAttributes redirectAttributes, + @AuthenticationPrincipal UserPrincipal principal) { + redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page); + userService.addFavorite(principal.getId(), id); + return Constants.REDIRECT_VIEW + Constants.API_URL + "/search"; + } +} diff --git a/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserService.java b/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserService.java index d1d8808..1436ca7 100644 --- a/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserService.java +++ b/SpringApp/library/src/main/java/com/ip/library/controllers/users/UserService.java @@ -16,27 +16,33 @@ import org.springframework.util.StringUtils; import com.ip.library.controllers.books.BookEntity; import com.ip.library.controllers.books.BookService; +import com.ip.library.controllers.favorites.FavoriteEntity; +import com.ip.library.controllers.favorites.FavoriteRepository; +import com.ip.library.controllers.favorites.UserBookId; import com.ip.library.core.configuration.Constants; import com.ip.library.core.error.NotFoundException; import com.ip.library.core.security.UserPrincipal; @Service public class UserService implements UserDetailsService{ - private final UserRepository repository; + private final UserRepository userRepository; + private final FavoriteRepository favoriteRepository; private final BookService bookService; private final PasswordEncoder passwordEncoder; public UserService( UserRepository repository, + FavoriteRepository favoriteRepository, BookService bookService, PasswordEncoder passwordEncoder) { - this.repository = repository; + this.userRepository = repository; + this.favoriteRepository = favoriteRepository; this.bookService = bookService; this.passwordEncoder = passwordEncoder; } private void checkLoginUniqueness(String name){ - if (repository.findByLoginIgnoreCase(name).isPresent()) { + if (userRepository.findByLoginIgnoreCase(name).isPresent()) { throw new IllegalArgumentException( String.format("Type with name %s already exists", name) ); @@ -45,23 +51,23 @@ public class UserService implements UserDetailsService{ @Transactional(readOnly = true) public List getAll() { - return StreamSupport.stream(repository.findAll().spliterator(), false).toList(); + return StreamSupport.stream(userRepository.findAll().spliterator(), false).toList(); } @Transactional(readOnly = true) public Page getAll(int page, int size) { - return repository.findAll(PageRequest.of(page, size)); + return userRepository.findAll(PageRequest.of(page, size)); } @Transactional(readOnly = true) public UserEntity get(long id) { - return repository.findById(id) + return userRepository.findById(id) .orElseThrow(() -> new NotFoundException(UserEntity.class, id)); } @Transactional(readOnly = true) public UserEntity getByLogin(String login) { - return repository.findByLoginIgnoreCase(login) + return userRepository.findByLoginIgnoreCase(login) .orElseThrow(() -> new IllegalArgumentException("Invalid login")); } @@ -77,7 +83,7 @@ public class UserService implements UserDetailsService{ passwordEncoder.encode( StringUtils.hasText(password.strip()) ? password : Constants.DEFAULT_PASSWORD)); entity.setRole(Optional.ofNullable(entity.getRole()).orElse(UserRole.USER)); - return repository.save(entity); + return userRepository.save(entity); } @Transactional @@ -85,13 +91,13 @@ public class UserService implements UserDetailsService{ final UserEntity existsEntity = get(id); checkLoginUniqueness(entity.getLogin()); existsEntity.setLogin(entity.getLogin()); - return repository.save(existsEntity); + return userRepository.save(existsEntity); } @Transactional public UserEntity delete(long id) { final UserEntity existsEntity = get(id); - repository.delete(existsEntity); + userRepository.delete(existsEntity); return existsEntity; } @@ -99,21 +105,21 @@ public class UserService implements UserDetailsService{ public UserEntity giveAdminRole(long id) { final UserEntity existsEntity = get(id); existsEntity.setRole(UserRole.ADMIN); - return repository.save(existsEntity); + return userRepository.save(existsEntity); } @Transactional public UserEntity giveUserRole(long id) { final UserEntity existsEntity = get(id); existsEntity.setRole(UserRole.USER); - return repository.save(existsEntity); + return userRepository.save(existsEntity); } @Transactional public UserEntity changePassword(long id, String newPassword) { final UserEntity existsEntity = get(id); existsEntity.setPassword(newPassword); - return repository.save(existsEntity); + return userRepository.save(existsEntity); } @Transactional @@ -123,14 +129,22 @@ public class UserService implements UserDetailsService{ return existsUser.addBook(book); } + @Transactional + public FavoriteEntity removeFavorite(long userId, long bookId) { + final FavoriteEntity existsEntity = favoriteRepository.findById(new UserBookId(userId, bookId)) + .orElseThrow(() -> new IllegalArgumentException("Invalid id")); + favoriteRepository.delete(existsEntity); + return existsEntity; + } + @Transactional(readOnly = true) public List getUserFavorities (long userId) { - return repository.getUserFavorities(userId); + return userRepository.getUserFavorities(userId); } @Transactional(readOnly = true) public Page getUserFavorities (long userId, int page, int size) { - return repository.getUserFavorities(userId, PageRequest.of(page, size)); + return userRepository.getUserFavorities(userId, PageRequest.of(page, size)); } @Override diff --git a/SpringApp/library/src/main/resources/templates/book-search.html b/SpringApp/library/src/main/resources/templates/book-search.html new file mode 100644 index 0000000..d2871f1 --- /dev/null +++ b/SpringApp/library/src/main/resources/templates/book-search.html @@ -0,0 +1,49 @@ + + + + + Поиск + + + +
+ +

Данные отсутствуют

+ +

Поиск

+ + + + + + + + + + + + + + + + + + + + +
IDНазваниеЖанрАвтор
+
+ + +
+
+
+ + +
+ + + \ No newline at end of file diff --git a/SpringApp/library/src/main/resources/templates/default.html b/SpringApp/library/src/main/resources/templates/default.html index 1d3c5b2..a324e19 100644 --- a/SpringApp/library/src/main/resources/templates/default.html +++ b/SpringApp/library/src/main/resources/templates/default.html @@ -28,6 +28,14 @@