ЛР4 фильмы работают с чекбоксами как надо

This commit is contained in:
ityurner02@mail.ru 2023-05-20 21:51:38 +04:00
parent e1fe87f1fa
commit 446e83c38e
10 changed files with 238 additions and 93 deletions

View File

@ -0,0 +1,217 @@
<script>
import 'axios';
import axios from "axios";
import Film from "../models/Film";
import Group from "../models/Genre";
export default {
created() {
this.getFilms();
this.getGenres();
},
mounted() {
const addModal = document.getElementById('editModal');
addModal.addEventListener('shown.bs.modal', function () {
})
const openModalForAdd = document.getElementById('openModalForAdd');
openModalForAdd.addEventListener('shown.bs.modal', function () {
})
},
data() {
return{
films: [],
URL: "http://localhost:8080/",
film: new Film(),
genres: [],
selectedGenres: [],
open: []
}
},
methods: {
getFilms(){
axios.get(this.URL + "film")
.then(response => {
this.films = response.data;
})
.catch(error => {
console.log(error);
});
},
addFilm(film){
console.log(film);
axios.post(this.URL + "film", film)
.then(() => {
this.getFilms();
this.closeModal();
})
.catch(error => {
console.log(error);
});
},
deleteFilm(id){
axios.delete(this.URL + `film/${id}`)
.then(() =>{
this.getFilms();
})
},
editFilm(film){
axios.put(this.URL + `film/${film.id}`, film)
.then(() =>{
const index = this.films.findIndex((s) => s.id === film.id);
if (index !== -1) {
this.films[index] = { ...film };
}
this.closeModal();
this.getFilms();
})
this.closeModal();
},
openModalForAdd(status, film = null) {
if (status === "create") {
this.film = new Film();
this.film.status = "create";
} else if (status === "edit" && film) {
this.film = { ...film };
this.film.status = "edit";
}
this.open = this.film.genreIds ? [...this.film.genreIds] : []; // Создаём новый массив, чтобы избежать проблем с ссылками
this.loadSelectedGenres();
document.getElementById("openModalForAdd").style.display = "block";
},
closeModalForAdd() {
document.getElementById("openModalForAdd").style.display = "none";
this.open = [...this.selectedGenres];
this.selectedGenres = [];
this.film = new Film();
},
openModal(status, film = null) {
if (status === "create") {
this.film = new Film();
this.film.status = "create";
} else if (status === "edit" && film) {
this.film = { ...film };
this.film.status = "edit";
}
document.getElementById("editModal").style.display = "block";
},
closeModal() {
document.getElementById("editModal").style.display = "none";
},
getGenres(){
axios.get(this.URL + "genre")
.then(response => {
this.genres = response.data;
console.log(response.data);
})
.catch(error => {
console.log(error);
});
},
saveSelectedGenres() {
this.open = [...this.selectedGenres];
},
loadSelectedGenres() {
this.selectedGenres = [...this.open];
},
addFilmGenre(id, list) {
axios
.post(this.URL + `film/add_genres/${id}`, list)
.then(() => {
this.closeModalForAdd();
this.getFilms();
this.open = [...this.selectedGenres];
})
.catch((error) => {
console.log(error);
});
}
}
}
</script>
<template>
<div class="container mt-4">
<h1 class="text-center mb-4">Фильмы</h1>
<button class="btn btn-success mr-2" @click="openModal('create')">Добавить</button>
<table class="table text-light">
<thead>
<tr>
<th>Название</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="flm in films" :key="flm.id">
<td>{{ flm.name }}</td>
<td>
<td>
<button class="btn btn-warning mr-2" @click="openModal('edit', flm)">Изменить</button>
</td>
<td>
<button class="btn btn-danger" @click="deleteFilm(flm.id)">Удалить</button>
</td>
<td>
<button class="btn btn-success mr-2" @click="openModalForAdd('edit', flm);">Добавить жанры</button>
</td>
</td>
</tr>
</tbody>
</table>
</div>
<!--Форма для создания фильмов-->
<div class="modal" tabindex="-1" id="editModal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Фильм</h5>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="name">Название:</label>
<input type="text" class="form-control" id="name" name="name" v-model="film.name">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="editModal" @click="closeModal()">Закрыть</button>
<button type="button" class="btn btn-primary" v-if="film.status === 'create'" @click="addFilm(film)">Создать</button>
<button type="button" class="btn btn-primary" v-else @click="editFilm(film)">Сохранить</button>
</div>
</div>
</div>
</div>
<!--Форма для привязки фильма и жанра -->
<div class="modal" tabindex="-1" id="openModalForAdd">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Добавление жанров</h5>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="name">Название:</label>
<input readonly type="text" class="form-control" id="name" name="name" v-model="film.name">
</div>
<div class="form-group">
<label for="name">Выберите жанры для добавления:</label>
<ul class="list-group">
<li class="list-group-item" v-for="genre in genres" :key="genre.id">
<div class="form-check">
<input class="form-check-input" type="checkbox" v-model="selectedGenres" :value="genre.id" v-bind:checked="open.includes(genre.id)" id="genreCheck{{ genre.id }}">
<label class="form-check-label" for="genreCheck{{ genre.id }}">{{ genre.name }}</label>
</div>
</li>
</ul>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="editModal" @click="closeModalForAdd()">Закрыть</button>
<button type="button" class="btn btn-primary" @click="addFilmGenre(film.id, selectedGenres)">Добавить</button>
</div>
</div>
</div>
</div>
</template>

View File

@ -83,6 +83,7 @@
<template> <template>
<div class="container mt-4"> <div class="container mt-4">
<h1 class="text-center mb-4">Жанры</h1>
<button class="btn btn-success mr-2" @click="openModal('create')">Добавить</button> <button class="btn btn-success mr-2" @click="openModal('create')">Добавить</button>
<table class="table text-light"> <table class="table text-light">
<thead> <thead>

View File

@ -3,11 +3,13 @@ import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue' import App from './App.vue'
import Index from './components/Index.vue' import Index from './components/Index.vue'
import CatalogGenres from './components/CatalogGenres.vue' import CatalogGenres from './components/CatalogGenres.vue'
import CatalogFilms from './components/CatalogFilms.vue'
const routes = [ const routes = [
{ path: '/', redirect: '/index' }, { path: '/', redirect: '/index' },
{ path: '/index', component: Index}, { path: '/index', component: Index},
{ path: '/catalogs/genres', component: CatalogGenres} { path: '/catalogs/genres', component: CatalogGenres},
{ path: '/catalogs/films', component: CatalogFilms}
] ]
const router = createRouter({ const router = createRouter({

View File

@ -1,26 +1,7 @@
export default class Collection { export default class Collection {
constructor(data) { constructor(data) {
this._id = data?.id; this.id = data?.id;
this._name = data?.name; this.name = data?.name;
this._filmIds = data?.filmIds; this.filmIds = data?.filmIds;
}
get id() {
return this._id;
}
get name() {
return this._name;
}
set name(value) {
if (typeof value !== 'string' || value === null || value.length == 0) {
throw 'New name value ' + value + ' is not a string or empty';
}
this._name = value;
}
get filmIds() {
return this._filmIds;
} }
} }

View File

@ -1,26 +1,7 @@
export default class Film { export default class Film {
constructor(data) { constructor(data) {
this._id = data?.id; this.id = data?.id;
this._name = data?.name; this.name = data?.name;
this._genreIds = data?.genreIds; this.genreIds = data?.genreIds;
}
get id() {
return this._id;
}
get name() {
return this._name;
}
set name(value) {
if (typeof value !== 'string' || value === null || value.length == 0) {
throw 'New name value ' + value + ' is not a string or empty';
}
this._name = value;
}
get genreIds() {
return this._genreIds;
} }
} }

Binary file not shown.

View File

@ -45,18 +45,8 @@ public class FilmController {
filmService.deleteAllFilms(); filmService.deleteAllFilms();
} }
@PostMapping("/add_genre/{id}") @PostMapping("/add_genres/{id}")
public FilmDTO addGenre(@PathVariable Long id, @RequestParam Long genre_id) { public FilmDTO addGenres(@PathVariable Long id, @RequestBody @Valid List<Long> genreIds) {
return new FilmDTO(filmService.addGenre(id, genre_id)); return new FilmDTO(filmService.addGenres(id, genreIds));
}
@DeleteMapping("/del_genre/{id}")
public FilmDTO delGenre(@PathVariable Long id, @RequestParam Long genre_id) {
return new FilmDTO(filmService.deleteGenre(id, genre_id));
}
@DeleteMapping("/del_genres/{id}")
public FilmDTO delGenres(@PathVariable Long id) {
return new FilmDTO(filmService.deleteGenres(id));
} }
} }

View File

@ -27,4 +27,6 @@ public class FilmDTO {
public List<Long> getGenreIds(){ public List<Long> getGenreIds(){
return genreIds; return genreIds;
} }
public void setId(long id){ this.id = id; }
public void setName(String name){ this.name = name; }
} }

View File

@ -17,9 +17,7 @@ public class GenreDTO {
public String getName(){ public String getName(){
return name; return name;
} }
public void setId(long id){ public void setId(long id){ this.id = id; }
this.id = id;
}
public void setName(String name){ public void setName(String name){
this.name = name; this.name = name;
} }

View File

@ -69,43 +69,16 @@ public class FilmService {
} }
@Transactional @Transactional
public Film addGenre(Long filmId, Long genreId) { public Film addGenres(Long filmId, List<Long> genreIds) {
Film film = findFilm(filmId); Film film = findFilm(filmId);
if (film == null) { if (film == null) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId)); throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
} }
final Genre genre = genreService.findGenre(genreId);
if (genre == null) {
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", genreId));
}
film.addGenre(genre);
return filmRepository.save(film);
}
@Transactional
public Film deleteGenre(Long filmId, Long genreId) {
Film film = findFilm(filmId);
if (film == null) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
final Genre genre = genreService.findGenre(genreId);
if (genre == null) {
throw new EntityNotFoundException(String.format("Genre with id [%s] is not found", genreId));
}
film.removeGenre(genre);
return filmRepository.save(film);
}
@Transactional
public Film deleteGenres(Long filmId) {
Film film = findFilm(filmId);
if (film == null) {
throw new EntityNotFoundException(String.format("Film with id [%s] is not found", filmId));
}
film.removeGenres(); film.removeGenres();
for(Long genreId : genreIds) {
final Genre genre = genreService.findGenre(genreId);
film.addGenre(genre);
}
return filmRepository.save(film); return filmRepository.save(film);
} }
} }