Ну допустим что-то есть
This commit is contained in:
parent
0ba91b1a06
commit
23c059922d
2
Laba5.1/.vscode/launch.json
vendored
2
Laba5.1/.vscode/launch.json
vendored
@ -6,7 +6,7 @@
|
||||
"request": "launch",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"mainClass": "com.example.demo.DemoApplication",
|
||||
"projectName": "lec7",
|
||||
"projectName": "Laba5.1",
|
||||
"args": "--populate",
|
||||
"envFile": "${workspaceFolder}/.env"
|
||||
}
|
||||
|
@ -11,12 +11,18 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
import com.example.demo.core.configuration.Constants;
|
||||
import com.example.demo.films.model.FilmEntity;
|
||||
import com.example.demo.films.service.FilmService;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.genres.service.GenreService;
|
||||
import com.example.demo.orders.model.OrderEntity;
|
||||
import com.example.demo.orders.service.OrderService;
|
||||
import com.example.demo.subscriptions.model.SubscriptionEntity;
|
||||
import com.example.demo.subscriptions.service.SubscriptionService;
|
||||
import com.example.demo.types.model.TypeEntity;
|
||||
import com.example.demo.types.service.TypeService;
|
||||
import com.example.demo.userfilms.model.UserfilmEntity;
|
||||
import com.example.demo.userfilms.service.UserfilmService;
|
||||
import com.example.demo.users.model.UserEntity;
|
||||
import com.example.demo.users.model.UserRole;
|
||||
import com.example.demo.users.service.UserService;
|
||||
@ -29,16 +35,25 @@ public class DemoApplication implements CommandLineRunner {
|
||||
private final SubscriptionService subscriptionService;
|
||||
private final UserService userService;
|
||||
private final OrderService orderService;
|
||||
private final GenreService genreService;
|
||||
private final FilmService filmService;
|
||||
private final UserfilmService userfilmService;
|
||||
|
||||
public DemoApplication(
|
||||
TypeService typeService,
|
||||
SubscriptionService subscriptionService,
|
||||
UserService userService,
|
||||
OrderService orderService) {
|
||||
OrderService orderService,
|
||||
GenreService genreService,
|
||||
FilmService filmService,
|
||||
UserfilmService userfilmService) {
|
||||
this.typeService = typeService;
|
||||
this.subscriptionService = subscriptionService;
|
||||
this.userService = userService;
|
||||
this.orderService = orderService;
|
||||
this.genreService = genreService;
|
||||
this.filmService = filmService;
|
||||
this.userfilmService = userfilmService;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
@ -79,6 +94,21 @@ public class DemoApplication implements CommandLineRunner {
|
||||
new OrderEntity(type3, 75000.00, 6),
|
||||
new OrderEntity(type3, 67800.00, 3));
|
||||
orders.forEach(order -> orderService.create(user1.getId(), order));
|
||||
|
||||
log.info("Create default genre values");
|
||||
final var genre1 = genreService.create(new GenreEntity("Comedy"));
|
||||
final var genre2 = genreService.create(new GenreEntity("Triller"));
|
||||
final var genre3 = genreService.create(new GenreEntity("Drama"));
|
||||
|
||||
log.info("Create default film values");
|
||||
final var film1 = filmService.create(new FilmEntity(genre1, "Ivan Vasilevich menyaet proffessiu"));
|
||||
final var film2 = filmService.create(new FilmEntity(genre2, "Ironia sudby"));
|
||||
final var film3 = filmService.create(new FilmEntity(genre3, "S legkim parom"));
|
||||
|
||||
log.info("Create default userfilm values");
|
||||
userfilmService.create(user1.getId(), new UserfilmEntity(film1));
|
||||
userfilmService.create(user1.getId(), new UserfilmEntity(film2));
|
||||
userfilmService.create(user1.getId(), new UserfilmEntity(film3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ public class Constants {
|
||||
|
||||
public static final String ADMIN_PREFIX = "/admin";
|
||||
|
||||
public static final String USER_COOKIE = "userIdCookie";
|
||||
|
||||
public static final String LOGIN_URL = "/login";
|
||||
public static final String LOGOUT_URL = "/logout";
|
||||
|
||||
|
@ -0,0 +1,104 @@
|
||||
package com.example.demo.films.api;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import com.example.demo.core.configuration.Constants;
|
||||
import com.example.demo.films.model.FilmEntity;
|
||||
import com.example.demo.films.service.FilmService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(FilmController.URL)
|
||||
public class FilmController {
|
||||
public static final String URL = Constants.ADMIN_PREFIX + "/film";
|
||||
private static final String FILM_VIEW = "film";
|
||||
private static final String FILM_EDIT_VIEW = "film-edit";
|
||||
private static final String FILM_ATTRIBUTE = "film";
|
||||
|
||||
private final FilmService filmService;
|
||||
private final ModelMapper modelMapper;
|
||||
|
||||
public FilmController(FilmService filmService, ModelMapper modelMapper) {
|
||||
this.filmService = filmService;
|
||||
this.modelMapper = modelMapper;
|
||||
}
|
||||
|
||||
private FilmDto toDto(FilmEntity entity) {
|
||||
return modelMapper.map(entity, FilmDto.class);
|
||||
}
|
||||
|
||||
private FilmEntity toEntity(FilmDto dto) {
|
||||
return modelMapper.map(dto, FilmEntity.class);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getAll(Model model) {
|
||||
model.addAttribute(
|
||||
"items",
|
||||
filmService.getAll().stream()
|
||||
.map(this::toDto)
|
||||
.toList());
|
||||
return FILM_VIEW;
|
||||
}
|
||||
|
||||
@GetMapping("/edit/")
|
||||
public String create(Model model) {
|
||||
model.addAttribute(FILM_ATTRIBUTE, new FilmDto());
|
||||
return FILM_EDIT_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/edit/")
|
||||
public String create(
|
||||
@ModelAttribute(name = FILM_ATTRIBUTE) @Valid FilmDto film,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
return FILM_EDIT_VIEW;
|
||||
}
|
||||
filmService.create(toEntity(film));
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
public String update(
|
||||
@PathVariable(name = "id") Long id,
|
||||
Model model) {
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
model.addAttribute(FILM_ATTRIBUTE, toDto(filmService.get(id)));
|
||||
return FILM_EDIT_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/edit/{id}")
|
||||
public String update(
|
||||
@PathVariable(name = "id") Long id,
|
||||
@ModelAttribute(name = FILM_ATTRIBUTE) @Valid FilmDto film,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
return FILM_EDIT_VIEW;
|
||||
}
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
filmService.update(id, toEntity(film));
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String delete(
|
||||
@PathVariable(name = "id") Long id) {
|
||||
filmService.delete(id);
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
package com.example.demo.films.api;
|
||||
|
||||
import groovyjarjarantlr4.v4.runtime.misc.NotNull;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public class FilmDto {
|
||||
private Long id;
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private String genreName;
|
||||
@NotBlank
|
||||
@Size(min = 5, max = 50)
|
||||
private String name;
|
||||
private String imageExtension;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getGenreName() {
|
||||
return genreName;
|
||||
}
|
||||
|
||||
public void setGenreName(String genreName) {
|
||||
this.genreName = genreName;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package com.example.demo.films.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.demo.core.model.BaseEntity;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.Lob;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "films")
|
||||
public class FilmEntity extends BaseEntity {
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "genreId", nullable = false)
|
||||
private GenreEntity genre;
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String name;
|
||||
private String imageExtension;
|
||||
@Lob
|
||||
private byte[] image;
|
||||
|
||||
public FilmEntity() {
|
||||
}
|
||||
|
||||
public FilmEntity(GenreEntity genre, String name) {
|
||||
this.name = name;
|
||||
this.genre = genre;
|
||||
}
|
||||
|
||||
public GenreEntity getGenre() {
|
||||
return genre;
|
||||
}
|
||||
|
||||
public void setGenre(GenreEntity genre) {
|
||||
this.genre = genre;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getImageExtension() {
|
||||
return imageExtension;
|
||||
}
|
||||
|
||||
public void setImageExtension(String imageExtension) {
|
||||
this.imageExtension = imageExtension;
|
||||
}
|
||||
|
||||
public byte[] getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(byte[] image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, genre, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
final FilmEntity other = (FilmEntity) obj;
|
||||
return Objects.equals(other.getId(), id)
|
||||
&& Objects.equals(other.getGenre(), genre)
|
||||
&& Objects.equals(other.getName(), name);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.example.demo.films.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
import com.example.demo.films.model.FilmEntity;
|
||||
|
||||
public interface FilmRepository
|
||||
extends CrudRepository<FilmEntity, Long>, PagingAndSortingRepository<FilmEntity, Long> {
|
||||
Optional<FilmEntity> findByNameIgnoreCase(String name);
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package com.example.demo.films.service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.example.demo.core.error.NotFoundException;
|
||||
import com.example.demo.films.model.FilmEntity;
|
||||
import com.example.demo.films.repository.FilmRepository;
|
||||
|
||||
@Service
|
||||
public class FilmService {
|
||||
private final FilmRepository repository;
|
||||
|
||||
public FilmService(FilmRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
private void checkName(Long id, String name) {
|
||||
final Optional<FilmEntity> existsFilm = repository.findByNameIgnoreCase(name);
|
||||
if (existsFilm.isPresent() && !existsFilm.get().getId().equals(id)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Film with name %s is already exists", name));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<FilmEntity> getAll() {
|
||||
return StreamSupport.stream(repository.findAll(Sort.by("id")).spliterator(), false).toList();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<FilmEntity> getByIds(Collection<Long> ids) {
|
||||
final List<FilmEntity> films = StreamSupport.stream(repository.findAllById(ids).spliterator(), false).toList();
|
||||
if (films.size() < ids.size()) {
|
||||
throw new IllegalArgumentException("Invalid film");
|
||||
}
|
||||
return films;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public FilmEntity get(long id) {
|
||||
return repository.findById(id)
|
||||
.orElseThrow(() -> new NotFoundException(FilmEntity.class, id));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FilmEntity create(FilmEntity entity) {
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException("Entity is null");
|
||||
}
|
||||
checkName(null, entity.getName());
|
||||
return repository.save(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FilmEntity update(Long id, FilmEntity entity) {
|
||||
final FilmEntity existsEntity = get(id);
|
||||
checkName(id, entity.getName());
|
||||
existsEntity.setName(entity.getName());
|
||||
existsEntity.setGenre(entity.getGenre());
|
||||
existsEntity.setImageExtension(entity.getImageExtension());
|
||||
existsEntity.setImage(entity.getImage());
|
||||
return repository.save(existsEntity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public FilmEntity delete(Long id) {
|
||||
final FilmEntity existsEntity = get(id);
|
||||
repository.delete(existsEntity);
|
||||
return existsEntity;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package com.example.demo.genres.api;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import com.example.demo.core.configuration.Constants;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.genres.service.GenreService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping(GenreController.URL)
|
||||
public class GenreController {
|
||||
public static final String URL = Constants.ADMIN_PREFIX + "/genre";
|
||||
private static final String GENRE_VIEW = "genre";
|
||||
private static final String GENRE_EDIT_VIEW = "genre-edit";
|
||||
private static final String GENRE_ATTRIBUTE = "genre";
|
||||
|
||||
private final GenreService genreService;
|
||||
private final ModelMapper modelMapper;
|
||||
|
||||
public GenreController(GenreService genreService, ModelMapper modelMapper) {
|
||||
this.genreService = genreService;
|
||||
this.modelMapper = modelMapper;
|
||||
}
|
||||
|
||||
private GenreDto toDto(GenreEntity entity) {
|
||||
return modelMapper.map(entity, GenreDto.class);
|
||||
}
|
||||
|
||||
private GenreEntity toEntity(GenreDto dto) {
|
||||
return modelMapper.map(dto, GenreEntity.class);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getAll(Model model) {
|
||||
model.addAttribute(
|
||||
"items",
|
||||
genreService.getAll().stream()
|
||||
.map(this::toDto)
|
||||
.toList());
|
||||
return GENRE_VIEW;
|
||||
}
|
||||
|
||||
@GetMapping("/edit/")
|
||||
public String create(Model model) {
|
||||
model.addAttribute(GENRE_ATTRIBUTE, new GenreDto());
|
||||
return GENRE_EDIT_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/edit/")
|
||||
public String create(
|
||||
@ModelAttribute(name = GENRE_ATTRIBUTE) @Valid GenreDto genre,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
return GENRE_EDIT_VIEW;
|
||||
}
|
||||
genreService.create(toEntity(genre));
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
|
||||
@GetMapping("/edit/{id}")
|
||||
public String update(
|
||||
@PathVariable(name = "id") Long id,
|
||||
Model model) {
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
model.addAttribute(GENRE_ATTRIBUTE, toDto(genreService.get(id)));
|
||||
return GENRE_EDIT_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/edit/{id}")
|
||||
public String update(
|
||||
@PathVariable(name = "id") Long id,
|
||||
@ModelAttribute(name = GENRE_ATTRIBUTE) @Valid GenreDto genre,
|
||||
BindingResult bindingResult,
|
||||
Model model) {
|
||||
if (bindingResult.hasErrors()) {
|
||||
return GENRE_EDIT_VIEW;
|
||||
}
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
genreService.update(id, toEntity(genre));
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String delete(
|
||||
@PathVariable(name = "id") Long id) {
|
||||
genreService.delete(id);
|
||||
return Constants.REDIRECT_VIEW + URL;
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.example.demo.genres.api;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
public class GenreDto {
|
||||
private Long id;
|
||||
@NotBlank
|
||||
@Size(min = 5, max = 50)
|
||||
private String name;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package com.example.demo.genres.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.demo.core.model.BaseEntity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "genres")
|
||||
public class GenreEntity extends BaseEntity {
|
||||
@Column(nullable = false, unique = true, length = 50)
|
||||
private String name;
|
||||
|
||||
public GenreEntity() {
|
||||
}
|
||||
|
||||
public GenreEntity(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
final GenreEntity other = (GenreEntity) obj;
|
||||
return Objects.equals(other.getId(), id)
|
||||
&& Objects.equals(other.getName(), name);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.example.demo.genres.repository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
|
||||
public interface GenreRepository
|
||||
extends CrudRepository<GenreEntity, Long>, PagingAndSortingRepository<GenreEntity, Long> {
|
||||
Optional<GenreEntity> findByNameIgnoreCase(String name);
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.example.demo.genres.service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.example.demo.core.error.NotFoundException;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.genres.repository.GenreRepository;
|
||||
|
||||
@Service
|
||||
public class GenreService {
|
||||
private final GenreRepository repository;
|
||||
|
||||
public GenreService(GenreRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
private void checkName(Long id, String name) {
|
||||
final Optional<GenreEntity> existsGenre = repository.findByNameIgnoreCase(name);
|
||||
if (existsGenre.isPresent() && !existsGenre.get().getId().equals(id)) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format("Genre with name %s is already exists", name));
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<GenreEntity> getAll() {
|
||||
return StreamSupport.stream(repository.findAll(Sort.by("id")).spliterator(), false).toList();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<GenreEntity> getByIds(Collection<Long> ids) {
|
||||
final List<GenreEntity> genres = StreamSupport.stream(repository.findAllById(ids).spliterator(), false)
|
||||
.toList();
|
||||
if (genres.size() < ids.size()) {
|
||||
throw new IllegalArgumentException("Invalid genre");
|
||||
}
|
||||
return genres;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public GenreEntity get(long id) {
|
||||
return repository.findById(id)
|
||||
.orElseThrow(() -> new NotFoundException(GenreEntity.class, id));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GenreEntity create(GenreEntity entity) {
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException("Entity is null");
|
||||
}
|
||||
checkName(null, entity.getName());
|
||||
return repository.save(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GenreEntity update(Long id, GenreEntity entity) {
|
||||
final GenreEntity existsEntity = get(id);
|
||||
checkName(id, entity.getName());
|
||||
existsEntity.setName(entity.getName());
|
||||
return repository.save(existsEntity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GenreEntity delete(Long id) {
|
||||
final GenreEntity existsEntity = get(id);
|
||||
repository.delete(existsEntity);
|
||||
return existsEntity;
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.example.demo.userfilms.api;
|
||||
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
|
||||
public class UserfilmDto {
|
||||
private Long id;
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private String filmName;
|
||||
@NotNull
|
||||
@Min(1)
|
||||
private String genreName;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFilmName() {
|
||||
return filmName;
|
||||
}
|
||||
|
||||
public void setFilmName(String filmName) {
|
||||
this.filmName = filmName;
|
||||
}
|
||||
|
||||
public String getGenreName() {
|
||||
return genreName;
|
||||
}
|
||||
|
||||
public void setGenreName(String genreName) {
|
||||
this.genreName = genreName;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.example.demo.userfilms.api;
|
||||
|
||||
public class UserfilmGroupedDto {
|
||||
private Long filmCount;
|
||||
private String genreName;
|
||||
|
||||
public Long getfilmCount() {
|
||||
return filmCount;
|
||||
}
|
||||
|
||||
public void setfilmCount(Long filmCount) {
|
||||
this.filmCount = filmCount;
|
||||
}
|
||||
|
||||
public String getGenreName() {
|
||||
return genreName;
|
||||
}
|
||||
|
||||
public void setGenreName(String genreName) {
|
||||
this.genreName = genreName;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package com.example.demo.userfilms.model;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.example.demo.core.model.BaseEntity;
|
||||
import com.example.demo.films.model.FilmEntity;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.users.model.UserEntity;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name = "userfilms")
|
||||
public class UserfilmEntity extends BaseEntity {
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "filmId", nullable = false)
|
||||
private FilmEntity film;
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "userId", nullable = false)
|
||||
private UserEntity user;
|
||||
@ManyToOne
|
||||
@JoinColumn(name = "genreId", nullable = false)
|
||||
private GenreEntity genre;
|
||||
|
||||
public UserfilmEntity() {
|
||||
}
|
||||
|
||||
public UserfilmEntity(FilmEntity film) {
|
||||
this.film = film;
|
||||
this.genre = film.getGenre();
|
||||
}
|
||||
|
||||
public GenreEntity getGenre() {
|
||||
return film.getGenre();
|
||||
}
|
||||
|
||||
public FilmEntity getFilm() {
|
||||
return film;
|
||||
}
|
||||
|
||||
public void setFilm(FilmEntity film) {
|
||||
this.film = film;
|
||||
}
|
||||
|
||||
public UserEntity getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(UserEntity user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, film, user.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
final UserfilmEntity other = (UserfilmEntity) obj;
|
||||
return Objects.equals(other.getId(), id)
|
||||
&& Objects.equals(other.getFilm(), film)
|
||||
&& Objects.equals(other.getUser().getId(), user.getId());
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.example.demo.userfilms.model;
|
||||
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
|
||||
public interface UserfilmGrouped {
|
||||
Long getCount();
|
||||
|
||||
GenreEntity getGenre();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package com.example.demo.userfilms.repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.PagingAndSortingRepository;
|
||||
|
||||
import com.example.demo.userfilms.model.UserfilmEntity;
|
||||
import com.example.demo.userfilms.model.UserfilmGrouped;
|
||||
|
||||
public interface UserfilmRepository
|
||||
extends CrudRepository<UserfilmEntity, Long>, PagingAndSortingRepository<UserfilmEntity, Long> {
|
||||
|
||||
Optional<UserfilmEntity> findOneByUserIdAndId(long userId, long id);
|
||||
|
||||
List<UserfilmEntity> findByUserId(long userId);
|
||||
|
||||
Page<UserfilmEntity> findByUserId(long userId, Pageable pageable);
|
||||
|
||||
List<UserfilmEntity> findByUserIdAndGenreId(long userId, long genreId);
|
||||
|
||||
Page<UserfilmEntity> findByUserIdAndGenreId(long userId, long genreId, Pageable pageable);
|
||||
|
||||
@Query("select "
|
||||
+ "count(*) as count, "
|
||||
+ "g as genre "
|
||||
+ "from FilmEntity f "
|
||||
+ "left join GenreEntity g "
|
||||
+ "on f.genre = g "
|
||||
+ "right join UserfilmEntity uf "
|
||||
+ "on uf.film = f and uf.user.id = ?1 "
|
||||
+ "group by g order by g.name")
|
||||
List<UserfilmGrouped> getFilmsTotalByGenre(long userId);
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package com.example.demo.userfilms.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.example.demo.core.error.NotFoundException;
|
||||
import com.example.demo.userfilms.model.UserfilmEntity;
|
||||
import com.example.demo.userfilms.model.UserfilmGrouped;
|
||||
import com.example.demo.userfilms.repository.UserfilmRepository;
|
||||
import com.example.demo.users.model.UserEntity;
|
||||
import com.example.demo.users.service.UserService;
|
||||
|
||||
@Service
|
||||
public class UserfilmService {
|
||||
private final UserfilmRepository repository;
|
||||
private final UserService userService;
|
||||
|
||||
public UserfilmService(UserfilmRepository repository, UserService userService) {
|
||||
this.repository = repository;
|
||||
this.userService = userService;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<UserfilmEntity> getAll(long userId, long genreId) {
|
||||
userService.get(userId);
|
||||
if (genreId <= 0L) {
|
||||
return repository.findByUserId(userId);
|
||||
} else {
|
||||
return repository.findByUserIdAndGenreId(userId, genreId);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<UserfilmEntity> getAll(long userId) {
|
||||
userService.get(userId);
|
||||
return repository.findByUserId(userId);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Page<UserfilmEntity> getAll(long userId, long genreId, int page, int size) {
|
||||
final Pageable pageable = PageRequest.of(page, size, Sort.by("id"));
|
||||
userService.get(userId);
|
||||
if (genreId <= 0L) {
|
||||
return repository.findByUserId(userId, pageable);
|
||||
} else {
|
||||
return repository.findByUserIdAndGenreId(userId, genreId, pageable);
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public UserfilmEntity get(long userId, long id) {
|
||||
userService.get(userId);
|
||||
return repository.findOneByUserIdAndId(userId, id)
|
||||
.orElseThrow(() -> new NotFoundException(UserfilmEntity.class, id));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserfilmEntity create(long userId, UserfilmEntity entity) {
|
||||
if (entity == null) {
|
||||
throw new IllegalArgumentException("Entity is null");
|
||||
}
|
||||
final UserEntity existsUser = userService.get(userId);
|
||||
entity.setUser(existsUser);
|
||||
return repository.save(entity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<UserfilmEntity> createAll(long userId, List<UserfilmEntity> entities) {
|
||||
if (entities == null || entities.isEmpty()) {
|
||||
throw new IllegalArgumentException("Userfilms list is null or empty");
|
||||
}
|
||||
final UserEntity existsUser = userService.get(userId);
|
||||
entities.forEach(entity -> entity.setUser(existsUser));
|
||||
return StreamSupport.stream(repository.saveAll(entities).spliterator(), false).toList();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserfilmEntity update(long userId, long id, UserfilmEntity entity) {
|
||||
userService.get(userId);
|
||||
final UserfilmEntity existsEntity = get(userId, id);
|
||||
existsEntity.setFilm(entity.getFilm());
|
||||
return repository.save(existsEntity);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public UserfilmEntity delete(long userId, long id) {
|
||||
userService.get(userId);
|
||||
final UserfilmEntity existsEntity = get(userId, id);
|
||||
repository.delete(existsEntity);
|
||||
return existsEntity;
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<UserfilmGrouped> getTotal(long userId) {
|
||||
userService.get(userId);
|
||||
return repository.getFilmsTotalByGenre(userId);
|
||||
}
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package com.example.demo.users.api;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
|
||||
|
||||
import com.example.demo.core.api.PageAttributesMapper;
|
||||
import com.example.demo.core.configuration.Constants;
|
||||
import com.example.demo.core.security.UserPrincipal;
|
||||
import com.example.demo.films.service.FilmService;
|
||||
import com.example.demo.genres.api.GenreDto;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.genres.service.GenreService;
|
||||
import com.example.demo.userfilms.api.UserfilmDto;
|
||||
import com.example.demo.userfilms.api.UserfilmGroupedDto;
|
||||
import com.example.demo.userfilms.model.UserfilmEntity;
|
||||
import com.example.demo.userfilms.model.UserfilmGrouped;
|
||||
import com.example.demo.userfilms.service.UserfilmService;
|
||||
import com.example.demo.users.model.UserSubscriptionWithStatus;
|
||||
import com.example.demo.users.service.UserService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/cabinet")
|
||||
public class UserCabinetController {
|
||||
|
||||
private static final String PROFILE_VIEW = "cabinet";
|
||||
|
||||
private static final String PAGE_ATTRIBUTE = "page";
|
||||
private static final String GENREID_ATTRIBUTE = "genreId";
|
||||
private static final String PROFILE_ATTRIBUTE = "profile";
|
||||
|
||||
private final UserfilmService userfilmService;
|
||||
private final GenreService genreService;
|
||||
private final FilmService filmService;
|
||||
private final UserService userService;
|
||||
private final ModelMapper modelMapper;
|
||||
|
||||
public UserCabinetController(
|
||||
UserfilmService userfilmService,
|
||||
GenreService genreService,
|
||||
FilmService filmService,
|
||||
UserService userService,
|
||||
ModelMapper modelMapper) {
|
||||
this.userfilmService = userfilmService;
|
||||
this.genreService = genreService;
|
||||
this.filmService = filmService;
|
||||
this.userService = userService;
|
||||
this.modelMapper = modelMapper;
|
||||
}
|
||||
|
||||
private GenreDto toGenreDto(GenreEntity entity) {
|
||||
return modelMapper.map(entity, GenreDto.class);
|
||||
}
|
||||
|
||||
private UserfilmDto toUserfilmDto(UserfilmEntity entity) {
|
||||
return modelMapper.map(entity, UserfilmDto.class);
|
||||
}
|
||||
|
||||
private UserfilmGroupedDto toUserfilmGroupedDto(UserfilmGrouped entity) {
|
||||
return modelMapper.map(entity, UserfilmGroupedDto.class);
|
||||
}
|
||||
|
||||
@GetMapping()
|
||||
public String getProfile(
|
||||
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
|
||||
@RequestParam(name = GENREID_ATTRIBUTE, defaultValue = "0") int genreId,
|
||||
Model model,
|
||||
@AuthenticationPrincipal UserPrincipal principal) {
|
||||
final long userId = principal.getId();
|
||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
||||
model.addAttribute(GENREID_ATTRIBUTE, genreId);
|
||||
model.addAllAttributes(PageAttributesMapper.toAttributes(
|
||||
userfilmService.getAll(userId, genreId, page, Constants.DEFUALT_PAGE_SIZE),
|
||||
this::toUserfilmDto));
|
||||
model.addAttribute("genres",
|
||||
genreService.getAll().stream()
|
||||
.map(this::toGenreDto)
|
||||
.toList());
|
||||
return PROFILE_VIEW;
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteUserfilm(
|
||||
@PathVariable(name = "id") Long id,
|
||||
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
|
||||
@RequestParam(name = GENREID_ATTRIBUTE, defaultValue = "0") int genreId,
|
||||
RedirectAttributes redirectAttributes,
|
||||
@AuthenticationPrincipal UserPrincipal principal) {
|
||||
redirectAttributes.addAttribute(PAGE_ATTRIBUTE, page);
|
||||
redirectAttributes.addAttribute(GENREID_ATTRIBUTE, genreId);
|
||||
userfilmService.delete(principal.getId(), id);
|
||||
return Constants.REDIRECT_VIEW + "/cabinet";
|
||||
}
|
||||
}
|
46
Laba5.1/src/main/resources/templates/cabinet.html
Normal file
46
Laba5.1/src/main/resources/templates/cabinet.html
Normal file
File diff suppressed because one or more lines are too long
@ -38,6 +38,14 @@
|
||||
th:classappend="${activeLink.startsWith('/admin/type') ? 'active' : ''}">
|
||||
Типы заказов
|
||||
</a>
|
||||
<a class="nav-link" href="/admin/genre"
|
||||
th:classappend="${activeLink.startsWith('/admin/genre') ? 'active' : ''}">
|
||||
Жанры фильмов
|
||||
</a>
|
||||
<a class="nav-link" href="/admin/film"
|
||||
th:classappend="${activeLink.startsWith('/admin/film') ? 'active' : ''}">
|
||||
Фильмы
|
||||
</a>
|
||||
<a class="nav-link" href="/admin/subscription"
|
||||
th:classappend="${activeLink.startsWith('/admin/subscription') ? 'active' : ''}">
|
||||
Списки рассылки
|
||||
@ -73,7 +81,7 @@
|
||||
</div>
|
||||
<div class="card-body d-flex flex-column">
|
||||
<div id="messages" class="flex-grow-1 pe-3">
|
||||
<!-- <div class="message d-flex flex-row justify-content-start mb-4">
|
||||
<div class="message d-flex flex-row justify-content-start mb-4">
|
||||
<img class="message-avatar" src="/einstein.svg" alt="avatar">
|
||||
<div class="p-3 ms-3 message-body message-in">
|
||||
<p class="small mb-0">
|
||||
@ -88,7 +96,7 @@
|
||||
</p>
|
||||
</div>
|
||||
<img class="message-avatar" src="/batman.svg" alt="avatar">
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text pt-2">
|
||||
<div data-mdb-input-init class="form-outline">
|
||||
|
36
Laba5.1/src/main/resources/templates/film-edit.html
Normal file
36
Laba5.1/src/main/resources/templates/film-edit.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
|
||||
|
||||
<head>
|
||||
<title>Редакторовать фильм</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content">
|
||||
<form action="#" th:action="@{/admin/film/edit/{id}(id=${film.id})}" th:object="${film}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="id" class="form-label">ID</label>
|
||||
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="genre" class="form-label">Товары</label>
|
||||
<select th:field="*{genreName}" id="genre" class="form-select">
|
||||
<option selected value="">Укажите тип товара</option>
|
||||
<option th:each="genre : ${genres}" th:value="${genre.id}">[[${genre.name}]]</option>
|
||||
</select>
|
||||
<div th:if="${#fields.hasErrors('genreName')}" th:errors="*{genreName}" class="invalid-feedback"></div>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Фильм</label>
|
||||
<input type="text" th:field="*{name}" id="name" class="form-control">
|
||||
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
|
||||
</div>
|
||||
<div class="mb-3 d-flex flex-row">
|
||||
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
|
||||
<a class="btn btn-secondary button-fixed-width" href="/admin/film">Отмена</a>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
50
Laba5.1/src/main/resources/templates/film.html
Normal file
50
Laba5.1/src/main/resources/templates/film.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
|
||||
|
||||
<head>
|
||||
<title>Фильмы</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content">
|
||||
<th:block th:switch="${items.size()}">
|
||||
<h2 th:case="0">Данные отсутствуют</h2>
|
||||
<th:block th:case="*">
|
||||
<h2>Фильмы</h2>
|
||||
<div>
|
||||
<a href="/admin/film/edit/" class="btn btn-primary">Добавить фильм</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-10">ID</th>
|
||||
<th scope="col" class="w-auto">Фильм</th>
|
||||
<th scope="col" class="w-10"></th>
|
||||
<th scope="col" class="w-10"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="film : ${items}">
|
||||
<th scope="row" th:text="${film.id}"></th>
|
||||
<td th:text="${film.name}"></td>
|
||||
<td>
|
||||
<form th:action="@{/admin/film/edit/{id}(id=${film.id})}" method="get">
|
||||
<button type="submit" class="btn btn-link button-link">Редактировать</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form th:action="@{/admin/film/delete/{id}(id=${film.id})}" method="post">
|
||||
<button type="submit" class="btn btn-link button-link"
|
||||
onclick="return confirm('Вы уверены?')">Удалить</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
28
Laba5.1/src/main/resources/templates/genre-edit.html
Normal file
28
Laba5.1/src/main/resources/templates/genre-edit.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
|
||||
|
||||
<head>
|
||||
<title>Редакторовать тип заказа</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content">
|
||||
<form action="#" th:action="@{/admin/genre/edit/{id}(id=${genre.id})}" th:object="${genre}" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="id" class="form-label">ID</label>
|
||||
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="name" class="form-label">Жанр фильма</label>
|
||||
<input type="text" th:field="*{name}" id="name" class="form-control">
|
||||
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" class="invalid-feedback"></div>
|
||||
</div>
|
||||
<div class="mb-3 d-flex flex-row">
|
||||
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
|
||||
<a class="btn btn-secondary button-fixed-width" href="/admin/genre">Отмена</a>
|
||||
</div>
|
||||
</form>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
50
Laba5.1/src/main/resources/templates/genre.html
Normal file
50
Laba5.1/src/main/resources/templates/genre.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ru" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
|
||||
|
||||
<head>
|
||||
<title>Жанры фильмов</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content">
|
||||
<th:block th:switch="${items.size()}">
|
||||
<h2 th:case="0">Данные отсутствуют</h2>
|
||||
<th:block th:case="*">
|
||||
<h2>Жанры фильмов</h2>
|
||||
<div>
|
||||
<a href="/admin/genre/edit/" class="btn btn-primary">Добавить новый жанр</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-10">ID</th>
|
||||
<th scope="col" class="w-auto">Жанр фильма</th>
|
||||
<th scope="col" class="w-10"></th>
|
||||
<th scope="col" class="w-10"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="genre : ${items}">
|
||||
<th scope="row" th:text="${genre.id}"></th>
|
||||
<td th:text="${genre.name}"></td>
|
||||
<td>
|
||||
<form th:action="@{/admin/genre/edit/{id}(id=${genre.id})}" method="get">
|
||||
<button type="submit" class="btn btn-link button-link">Редактировать</button>
|
||||
</form>
|
||||
</td>
|
||||
<td>
|
||||
<form th:action="@{/admin/genre/delete/{id}(id=${genre.id})}" method="post">
|
||||
<button type="submit" class="btn btn-link button-link"
|
||||
onclick="return confirm('Вы уверены?')">Удалить</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
70
Laba5.1/src/main/resources/templates/userfilms.html
Normal file
70
Laba5.1/src/main/resources/templates/userfilms.html
Normal file
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
|
||||
<body>
|
||||
<th:block th:fragment="userfilms (items, totalPages, currentPage)">
|
||||
<th:block th:switch="${items.size()}">
|
||||
<h2 th:case="0">Данные отсутствуют</h2>
|
||||
<th:block th:case="*">
|
||||
<form th:action="@{/cabinet}" method="get" class="row mt-2">
|
||||
<div class="col-sm-10">
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<select th:name="genreId" id="genreId" class="form-select">
|
||||
<option selected value="">Фильтр по типу товара</option>
|
||||
<option th:each="genre : ${genres}" th:value="${genre.id}"
|
||||
th:selected="${genre.id==genreId}">
|
||||
[[${genre.name}]]
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary col-sm-2">Показать</button>
|
||||
</form>
|
||||
<table class="table mt-2">
|
||||
<caption></caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-10">ID</th>
|
||||
<th scope="col" class="w-auto">Тип заказа</th>
|
||||
<th scope="col" class="w-10"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<div>
|
||||
<ul class="list-group flex-row flex-wrap">
|
||||
<li th:each="userfilm : ${items}" class="list-group-item col-sm-6">
|
||||
<strong>[[${userfilm.filmName}]]</strong> : [[${userfilm.genreName}]]
|
||||
<form th:action="@{/cabinet/delete/{id}(id=${userfilm.id})}" method="post">
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<input type="hidden" th:name="filmId" th:value="${filmId}">
|
||||
<button type="submit" class="btn btn-link button-link"
|
||||
onclick="return confirm('Вы уверены?')">Удалить</button>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<tbody>
|
||||
<tr th:each="userfilm : ${items}">
|
||||
<th scope="row" th:text="${userfilm.id}"></th>
|
||||
<td th:text="${userfilm.filmName}"></td>
|
||||
<td>
|
||||
<form th:action="@{cabinet//delete/{id}(id=${userfilm.id})}" method="post">
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<input type="hidden" th:name="filmId" th:value="${filmId}">
|
||||
<button type="submit" class="btn btn-link button-link"
|
||||
onclick="return confirm('Вы уверены?')">Удалить</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</th:block>
|
||||
<th:block th:replace="~{ pagination :: pagination (
|
||||
url='',
|
||||
totalPages=${totalPages},
|
||||
currentPage=${currentPage}) }" />
|
||||
</th:block>
|
||||
</th:block>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user