положено начало выбору в избранное для фильмоы просто в каталоге
This commit is contained in:
parent
a53c4fff2d
commit
463296c358
@ -8,6 +8,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|||||||
|
|
||||||
import com.example.backend.categories.model.CategorieEntity;
|
import com.example.backend.categories.model.CategorieEntity;
|
||||||
import com.example.backend.categories.service.CategorieService;
|
import com.example.backend.categories.service.CategorieService;
|
||||||
|
import com.example.backend.favorites.model.FavoriteEntity;
|
||||||
|
import com.example.backend.favorites.service.FavoriteService;
|
||||||
import com.example.backend.movies.model.MovieEntity;
|
import com.example.backend.movies.model.MovieEntity;
|
||||||
import com.example.backend.movies.service.MovieService;
|
import com.example.backend.movies.service.MovieService;
|
||||||
import com.example.backend.users.service.UserService;
|
import com.example.backend.users.service.UserService;
|
||||||
@ -21,12 +23,15 @@ public class BackendApplication implements CommandLineRunner {
|
|||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
private final CategorieService categorieService;
|
private final CategorieService categorieService;
|
||||||
private final MovieService movieService;
|
private final MovieService movieService;
|
||||||
|
private final FavoriteService favoriyService;
|
||||||
|
|
||||||
public BackendApplication(UserService userService,
|
public BackendApplication(UserService userService,
|
||||||
CategorieService categorieService,
|
CategorieService categorieService,
|
||||||
MovieService movieService) {
|
MovieService movieService,
|
||||||
|
FavoriteService favoriyService) {
|
||||||
this.userService = userService;
|
this.userService = userService;
|
||||||
this.categorieService = categorieService;
|
this.categorieService = categorieService;
|
||||||
|
this.favoriyService = favoriyService;
|
||||||
this.movieService = movieService;
|
this.movieService = movieService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,6 +89,11 @@ public class BackendApplication implements CommandLineRunner {
|
|||||||
// categorieService.create(cat4);
|
// categorieService.create(cat4);
|
||||||
// categorieService.create(cat5);
|
// categorieService.create(cat5);
|
||||||
// movieService.create(mov1);
|
// movieService.create(mov1);
|
||||||
|
favoriyService.create(new FavoriteEntity(null, userService.get(2), movieService.get(98)));
|
||||||
|
// movieService.get(98));
|
||||||
|
// for (var fav : favoriyService.getAll(2)) {
|
||||||
|
// favoriyService.delete(fav.getId());
|
||||||
|
// }
|
||||||
|
|
||||||
_logger.info("The program is started");
|
_logger.info("The program is started");
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,10 @@ import org.springframework.data.repository.CrudRepository;
|
|||||||
import com.example.backend.favorites.model.FavoriteEntity;
|
import com.example.backend.favorites.model.FavoriteEntity;
|
||||||
|
|
||||||
public interface FavoriteRepository extends CrudRepository<FavoriteEntity, Integer> {
|
public interface FavoriteRepository extends CrudRepository<FavoriteEntity, Integer> {
|
||||||
|
|
||||||
List<FavoriteEntity> findByUserId(Integer userId);
|
List<FavoriteEntity> findByUserId(Integer userId);
|
||||||
|
|
||||||
|
List<FavoriteEntity> findByUserIdAndMovieId(Integer userId, Integer movieId);
|
||||||
|
|
||||||
Optional<FavoriteEntity> findOneByUserIdAndId(Integer userId, Integer id);
|
Optional<FavoriteEntity> findOneByUserIdAndId(Integer userId, Integer id);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,12 @@ public class FavoriteService {
|
|||||||
return repository.findById(id).orElseThrow(() -> new NotFoundException(FavoriteEntity.class, id));
|
return repository.findById(id).orElseThrow(() -> new NotFoundException(FavoriteEntity.class, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Transactional(readOnly = true)
|
||||||
|
// public List<FavoriteEntity> getForAddToFavorite(Integer userId, Integer
|
||||||
|
// movieId) {
|
||||||
|
// return repository.findByUserIdAndMovieId(userId, movieId);
|
||||||
|
// }
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public FavoriteEntity create(FavoriteEntity entity) {
|
public FavoriteEntity create(FavoriteEntity entity) {
|
||||||
return repository.save(entity);
|
return repository.save(entity);
|
||||||
|
@ -1,19 +1,26 @@
|
|||||||
package com.example.backend.movies.api;
|
package com.example.backend.movies.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.modelmapper.ModelMapper;
|
import org.modelmapper.ModelMapper;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||||
|
|
||||||
import com.example.backend.categories.service.CategorieService;
|
import com.example.backend.categories.service.CategorieService;
|
||||||
import com.example.backend.core.configurations.Constants;
|
import com.example.backend.core.configurations.Constants;
|
||||||
|
import com.example.backend.favorites.model.FavoriteEntity;
|
||||||
|
import com.example.backend.favorites.service.FavoriteService;
|
||||||
import com.example.backend.movies.model.MovieEntity;
|
import com.example.backend.movies.model.MovieEntity;
|
||||||
import com.example.backend.movies.service.MovieService;
|
import com.example.backend.movies.service.MovieService;
|
||||||
|
import com.example.backend.users.service.UserService;
|
||||||
|
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
@ -34,12 +41,21 @@ public class MovieUserController {
|
|||||||
|
|
||||||
private final MovieService movieService;
|
private final MovieService movieService;
|
||||||
private final CategorieService categorieService;
|
private final CategorieService categorieService;
|
||||||
|
private final UserService userService;
|
||||||
|
private final FavoriteService favoriteService;
|
||||||
|
|
||||||
private final ModelMapper modelMapper;
|
private final ModelMapper modelMapper;
|
||||||
|
|
||||||
public MovieUserController(MovieService movieService, CategorieService categorieService, ModelMapper modelMapper) {
|
public MovieUserController(MovieService movieService,
|
||||||
|
CategorieService categorieService,
|
||||||
|
ModelMapper modelMapper,
|
||||||
|
UserService userService,
|
||||||
|
FavoriteService favoriteService) {
|
||||||
this.modelMapper = modelMapper;
|
this.modelMapper = modelMapper;
|
||||||
this.categorieService = categorieService;
|
this.categorieService = categorieService;
|
||||||
this.movieService = movieService;
|
this.movieService = movieService;
|
||||||
|
this.userService = userService;
|
||||||
|
this.favoriteService = favoriteService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MovieDTO toDto(MovieEntity entity) {
|
private MovieDTO toDto(MovieEntity entity) {
|
||||||
@ -60,9 +76,15 @@ public class MovieUserController {
|
|||||||
.stream()
|
.stream()
|
||||||
.map(this::toDto)
|
.map(this::toDto)
|
||||||
.toList());
|
.toList());
|
||||||
|
model.addAttribute(CATEGORIEID_ATTRIBUTE, model);
|
||||||
model.addAttribute("categories", categorieService.getAll());
|
model.addAttribute("categories", categorieService.getAll());
|
||||||
|
|
||||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
Integer currentUserId = userService.getCurrentUserId(authentication.getName());
|
||||||
|
|
||||||
|
List<FavoriteEntity> favs = favoriteService.getAll(currentUserId);
|
||||||
|
|
||||||
|
model.addAttribute("favorites", favs);
|
||||||
model.addAttribute(CATEGORIEID_ATTRIBUTE, 0);
|
model.addAttribute(CATEGORIEID_ATTRIBUTE, 0);
|
||||||
return MOVIE_VIEW;
|
return MOVIE_VIEW;
|
||||||
}
|
}
|
||||||
@ -76,13 +98,25 @@ public class MovieUserController {
|
|||||||
.stream()
|
.stream()
|
||||||
.map(this::toDto)
|
.map(this::toDto)
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
model.addAttribute("categories", categorieService.getAll());
|
model.addAttribute("categories", categorieService.getAll());
|
||||||
|
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
Integer currentUserId = userService.getCurrentUserId(authentication.getName());
|
||||||
|
|
||||||
|
List<FavoriteEntity> favs = favoriteService.getAll(currentUserId);
|
||||||
|
|
||||||
|
model.addAttribute("favorites", favs);
|
||||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
model.addAttribute(PAGE_ATTRIBUTE, page);
|
||||||
model.addAttribute(CATEGORIEID_ATTRIBUTE, categorieId);
|
model.addAttribute(CATEGORIEID_ATTRIBUTE, categorieId);
|
||||||
return MOVIE_VIEW;
|
return MOVIE_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/addToFavorite/{id}")
|
||||||
|
public String changeStatusForFavorite() {
|
||||||
|
return Constants.REDIRECT_VIEW + URL;
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/countView")
|
@GetMapping("/countView")
|
||||||
public Integer countView(@RequestParam(name = "movieId", defaultValue = "0") Integer movieId) {
|
public Integer countView(@RequestParam(name = "movieId", defaultValue = "0") Integer movieId) {
|
||||||
return movieService.countView(movieId);
|
return movieService.countView(movieId);
|
||||||
|
@ -9,4 +9,6 @@ import com.example.backend.users.model.UserEntity;
|
|||||||
public interface UserRepository
|
public interface UserRepository
|
||||||
extends CrudRepository<UserEntity, Integer>, PagingAndSortingRepository<UserEntity, Integer> {
|
extends CrudRepository<UserEntity, Integer>, PagingAndSortingRepository<UserEntity, Integer> {
|
||||||
Optional<UserEntity> findByLoginIgnoreCase(String login);
|
Optional<UserEntity> findByLoginIgnoreCase(String login);
|
||||||
|
|
||||||
|
Integer getIdByLoginIgnoreCase(String login);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ import org.springframework.security.core.userdetails.UserDetails;
|
|||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
@ -26,6 +27,7 @@ import com.example.backend.users.repository.UserRepository;
|
|||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UserService implements UserDetailsService {
|
public class UserService implements UserDetailsService {
|
||||||
|
|
||||||
private final UserRepository repository;
|
private final UserRepository repository;
|
||||||
private final PasswordEncoder passwordEncoder;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
|
||||||
@ -96,10 +98,20 @@ public class UserService implements UserDetailsService {
|
|||||||
return existsentity;
|
return existsentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public Integer getCurrentUserId(String name) {
|
||||||
|
final Optional<UserEntity> user = repository.findByLoginIgnoreCase(name);
|
||||||
|
if (user.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
return user.get().getId();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
final UserEntity existUser = getByUsername(username);
|
final UserEntity existUser = getByUsername(username);
|
||||||
return new UserPrincipal(existUser);
|
return new UserPrincipal(existUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
<input class="form-control" type="text" id="duration" th:field="*{duration}" />
|
<input class="form-control" type="text" id="duration" th:field="*{duration}" />
|
||||||
<div th:if="${#fields.hasErrors('duration')}" th:errors="*{duration}" class="invalid-feedback"></div>
|
<div th:if="${#fields.hasErrors('duration')}" th:errors="*{duration}" class="invalid-feedback"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<label class="form-label" for="categorie">Категория:</label>
|
<label class="form-label" for="categorie">Категория:</label>
|
||||||
<select th:field="*{categorieId}" id="categorie" class="form-select">
|
<select th:field="*{categorieId}" id="categorie" class="form-select">
|
||||||
@ -40,6 +41,7 @@
|
|||||||
<div th:if="${#fields.hasErrors('categorieId')}" th:errors="*{categorieId}" class="invalid-feedback">
|
<div th:if="${#fields.hasErrors('categorieId')}" th:errors="*{categorieId}" class="invalid-feedback">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-3 d-flex flex-row">
|
<div class="mb-3 d-flex flex-row">
|
||||||
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
|
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
|
||||||
<a class="btn btn-secondary button-fixed-width" th:href="@{/admin/movies(page=${page})}">Отмена</a>
|
<a class="btn btn-secondary button-fixed-width" th:href="@{/admin/movies(page=${page})}">Отмена</a>
|
||||||
|
@ -85,10 +85,25 @@
|
|||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<th:block sec:authorize="hasRole('USER')">
|
<th:block sec:authorize="hasRole('USER')">
|
||||||
<th:block th:switch="${movies.size()}">
|
<th:block th:switch="${movies.size()}">
|
||||||
<h2 th:case="0">Данные отсутствуют</h2>
|
<h2 th:case="0">Данные отсутствуют</h2>
|
||||||
<th:block th:case="*">
|
<th:block th:case="*">
|
||||||
|
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<th:block th:switch="${viewes.size()}">
|
||||||
|
<h2 th:case="0">
|
||||||
|
д етить колотить
|
||||||
|
</h2>
|
||||||
|
<th:block th:case="*">
|
||||||
|
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
</th:block> -->
|
||||||
|
|
||||||
|
|
||||||
<div class="categories-container d-flex flex-row justify-content-center mt-3 mb-3">
|
<div class="categories-container d-flex flex-row justify-content-center mt-3 mb-3">
|
||||||
<div class="category-item d-flex flex-column justify-content-center align-items-center mb-5 mb-md-0"
|
<div class="category-item d-flex flex-column justify-content-center align-items-center mb-5 mb-md-0"
|
||||||
th:each="movie : ${movies}">
|
th:each="movie : ${movies}">
|
||||||
@ -99,39 +114,69 @@
|
|||||||
<h5 class="card-title" th:text="${movie.name}"></h5>
|
<h5 class="card-title" th:text="${movie.name}"></h5>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-row me-ms-mt-2">
|
|
||||||
<!-- <form th:action="@{/movies/edit/{id}(id=${movie.id})}" method="get"> -->
|
|
||||||
<input type="hidden" th:name="page" th:value="${page}">
|
<div class="d-flex flex-row ms-mt-2">
|
||||||
<button type="submit" class="btn btn-link button-link">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
<th:block th:switch="${favorites.size()}">
|
||||||
class="bi bi-heart-fill" viewBox="0 0 16 16">
|
<h2 th:case="0">
|
||||||
<path fill-rule="evenodd"
|
д етить колотить
|
||||||
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314" />
|
</h2>
|
||||||
</svg>
|
|
||||||
</button>
|
<th:block th:case="*">
|
||||||
<!-- </form> -->
|
<form th:action="@{/movies/addToFavorite/{id}(id=${movie.id})}" method="get">
|
||||||
<!-- <form th:action="@{/movies/delete/{id}(id=${movie.id})}" method="post"> -->
|
<input type="hidden" th:name="page" th:value="${page}">
|
||||||
<input type="hidden" th:name="page" th:value="${page}">
|
<!-- <div th:each="fav : ${favorites}"> -->
|
||||||
<button type="submit" class="btn btn-link button-link"
|
<button type="submit" class="btn btn-link button-link"
|
||||||
onclick="return confirm('Вы уверены?')">
|
th:each="fav : ${favorites}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
<svg th:if="${fav.movie.id} == ${movie.id}"
|
||||||
class="bi bi-eye-fill" viewBox="0 0 16 16">
|
xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
||||||
<path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0" />
|
fill="currentColor" class="bi bi-heart-fill" viewBox="0 0 16 16">
|
||||||
<path
|
<path fill-rule="evenodd"
|
||||||
d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8m8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7" />
|
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
<svg th:if="${fav.movie.id} != ${movie.id}"
|
||||||
<!-- </form> -->
|
xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
||||||
|
fill="currentColor" class="bi bi-heart" viewBox="0 0 16 16">
|
||||||
|
<path fill-rule="evenodd"
|
||||||
|
d="M8 1.314C12.438-3.248 23.534 4.735 8 15-7.534 4.736 3.562-3.248 8 1.314" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<!-- </div> -->
|
||||||
|
</form>
|
||||||
|
</th:block>
|
||||||
|
</th:block>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
</th:block>
|
</th:block>
|
||||||
<th:block th:replace="~{ pagination :: pagination (
|
|
||||||
|
<!-- <form th:action="@{/movies/delete/{id}(id=${movie.id})}" method="post"> -->
|
||||||
|
<!-- <input type="hidden" th:name="page" th:value="${page}">
|
||||||
|
<button type="submit" class="btn btn-link button-link" onclick="return confirm('Вы уверены?')">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor"
|
||||||
|
class="bi bi-eye-fill" viewBox="0 0 16 16">
|
||||||
|
<path d="M10.5 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0" />
|
||||||
|
<path
|
||||||
|
d="M0 8s3-5.5 8-5.5S16 8 16 8s-3 5.5-8 5.5S0 8 0 8m8 3.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7" />
|
||||||
|
</svg>
|
||||||
|
</button> -->
|
||||||
|
<!-- </form> -->
|
||||||
|
<!-- </div>
|
||||||
|
</div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
<th:block th:replace="~{ pagination :: pagination (
|
||||||
url=${'movies'},
|
url=${'movies'},
|
||||||
totalPages=${totalPages},
|
totalPages=${totalPages},
|
||||||
currentPage=${currentPage}) }" />
|
currentPage=${currentPage}) }">
|
||||||
|
</th:block>
|
||||||
|
|
||||||
|
</th:block>
|
||||||
</th:block>
|
</th:block>
|
||||||
|
|
||||||
|
|
||||||
|
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user