Почти всё, ура
This commit is contained in:
parent
fa6f53bd8a
commit
3a9239b77e
@ -26,6 +26,11 @@ public class AuthorController {
|
||||
return authorService.findAllAuthors().stream().map(AuthorDto::new).toList();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/books")
|
||||
public List<BookDto> getAuthorBooks(@PathVariable Long id){
|
||||
return authorService.authorBooks(id).stream().map(BookDto::new).toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public AuthorDto createAuthor(@RequestBody @Valid AuthorDto authorDto) throws IOException {
|
||||
return new AuthorDto(authorService.addAuthor(authorDto));
|
||||
|
@ -26,6 +26,11 @@ public class BookController {
|
||||
return bookService.findAllBooks().stream().map(BookDto::new).toList();
|
||||
}
|
||||
|
||||
@GetMapping("/{id}/genres")
|
||||
public List<GenreDto> getBookGenres(@PathVariable Long id){
|
||||
return bookService.bookGenres(id).stream().map(GenreDto::new).toList();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public BookDto createBook(@RequestBody @Valid BookDto bookDto) throws IOException {
|
||||
return new BookDto(bookService.addBook(bookDto));
|
||||
|
@ -66,6 +66,11 @@ public class AuthorService {
|
||||
return authorRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Book> authorBooks(Long id){
|
||||
return authorRepository.findById(id).get().getBooks();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Author updateAuthor(Long id, String firstname, String lastname, File photo){
|
||||
if (!StringUtils.hasText(firstname) || !StringUtils.hasText(lastname)) {
|
||||
|
@ -6,6 +6,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import ru.ip.labworks.labworks.bookshop.controller.BookDto;
|
||||
import ru.ip.labworks.labworks.bookshop.model.Book;
|
||||
import ru.ip.labworks.labworks.bookshop.model.Genre;
|
||||
import ru.ip.labworks.labworks.bookshop.repository.BookRepository;
|
||||
import ru.ip.labworks.labworks.bookshop.repository.GenreRepository;
|
||||
import ru.ip.labworks.labworks.util.validation.ValidatorUtil;
|
||||
@ -70,6 +71,11 @@ public class BookService {
|
||||
return bookRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Genre> bookGenres(Long id){
|
||||
return bookRepository.findById(id).get().getGenres();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Book updateBook(Long id, String name, String release, File cover) {
|
||||
if (!StringUtils.hasText(name) || !StringUtils.hasText(release)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<footer class="container pt-4 my-md-5 pt-md-5 text-center fixed-bottom border-top">
|
||||
<footer class="container pt-4 my-md-5 pt-md-5 text-center border-top">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md">
|
||||
<h5 class=""><strong>End</strong></h5>
|
||||
|
@ -1,10 +1,20 @@
|
||||
<template>
|
||||
<header class="fixed-top">
|
||||
<nav class="navbar navbar-expand-lg bg-primary" data-bs-theme="dark">
|
||||
<nav class="navbar navbar-expand-lg bg-success" data-bs-theme="dark">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="#">
|
||||
<strong>{ DTC } Data Type Calculator</strong>
|
||||
<strong>{ OBS } Online Book Service</strong>
|
||||
</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
|
||||
<div class="navbar-nav">
|
||||
<a class="nav-link active" aria-current="page" href="/authors">Authors</a>
|
||||
<a class="nav-link" href="/books">Books</a>
|
||||
<a class="nav-link" href="/genres">Genres</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
8
src/main/resources/frontend/spa-vue/src/models/Author.js
Normal file
8
src/main/resources/frontend/spa-vue/src/models/Author.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default class Author{
|
||||
constructor(data){
|
||||
this.id = data?.id;
|
||||
this.firstname = data?.firstname;
|
||||
this.lastname = data?.lastname;
|
||||
this.photo = data?.photo;
|
||||
}
|
||||
}
|
8
src/main/resources/frontend/spa-vue/src/models/Book.js
Normal file
8
src/main/resources/frontend/spa-vue/src/models/Book.js
Normal file
@ -0,0 +1,8 @@
|
||||
export default class Book{
|
||||
constructor(data){
|
||||
this.id = data?.id;
|
||||
this.name = data?.name;
|
||||
this.release = data?.release;
|
||||
this.cover = data?.cover;
|
||||
}
|
||||
}
|
6
src/main/resources/frontend/spa-vue/src/models/Genre.js
Normal file
6
src/main/resources/frontend/spa-vue/src/models/Genre.js
Normal file
@ -0,0 +1,6 @@
|
||||
export default class Genre{
|
||||
constructor(data){
|
||||
this.id = data?.id;
|
||||
this.name = data?.name;
|
||||
}
|
||||
}
|
245
src/main/resources/frontend/spa-vue/src/pages/Authors.vue
Normal file
245
src/main/resources/frontend/spa-vue/src/pages/Authors.vue
Normal file
@ -0,0 +1,245 @@
|
||||
<script>
|
||||
import 'axios';
|
||||
import axios from "axios";
|
||||
import Header from '../components/Header.vue';
|
||||
import Footer from '../components/Footer.vue';
|
||||
import Author from '../models/Author';
|
||||
import Book from '../models/Book';
|
||||
export default{
|
||||
components:{
|
||||
Header,
|
||||
Footer
|
||||
},
|
||||
created(){
|
||||
this.getAuthors();
|
||||
},
|
||||
mounted() {
|
||||
const addModal = document.getElementById('editModal');
|
||||
addModal.addEventListener('shown.bs.modal', function () {
|
||||
})
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
authors: [],
|
||||
authorBooks: [],
|
||||
allBooks: [],
|
||||
bookid: 0,
|
||||
URL: "http://localhost:8080/",
|
||||
author: new Author(),
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getAuthors(){
|
||||
axios.get(this.URL + "author")
|
||||
.then(response => {
|
||||
this.authors = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
async addAuthor(){
|
||||
await this.toBase64();
|
||||
console.log(this.author);
|
||||
axios.post(this.URL + "author", this.author)
|
||||
.then(() => {
|
||||
this.getAuthors();
|
||||
this.closeModal();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
deleteAuthor(id){
|
||||
axios.delete(this.URL + `author/${id}`)
|
||||
.then(() =>{
|
||||
this.getAuthors();
|
||||
})
|
||||
},
|
||||
async updateAuthor(author){
|
||||
if(author.photo === undefined) await this.toBase64();
|
||||
axios.put(this.URL + `author/${author.id}`, this.author)
|
||||
.then(() =>{
|
||||
this.getAuthors();
|
||||
})
|
||||
this.closeModal();
|
||||
},
|
||||
openModal() {
|
||||
document.getElementById("editModal").style.display = "block";
|
||||
},
|
||||
openManyToManyModal(){
|
||||
this.getAuthorBooks();
|
||||
this.getAllBooks();
|
||||
document.getElementById("manyToManyModal").style.display = "block";
|
||||
},
|
||||
closeModal() {
|
||||
document.getElementById("editModal").style.display = "none";
|
||||
this.author = new Object();
|
||||
},
|
||||
closeManyToManyModal() {
|
||||
document.getElementById("manyToManyModal").style.display = "none";
|
||||
},
|
||||
async toBase64(){
|
||||
var file = document.getElementById("photo").files[0];
|
||||
var reader = new FileReader();
|
||||
var phototemp = this.author;
|
||||
reader.readAsDataURL(file);
|
||||
await new Promise((resolve, reject) => {
|
||||
reader.onload = function () {
|
||||
phototemp.photo = reader.result;
|
||||
console.log(phototemp);
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
console.log('Error: ', error);
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
},
|
||||
getAllBooks(){
|
||||
axios.get(this.URL + "book")
|
||||
.then(response => {
|
||||
this.allBooks = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
getAuthorBooks(){
|
||||
axios.get(this.URL + `author/${this.author.id}/books`)
|
||||
.then(response => {
|
||||
this.authorBooks = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
addBook(){
|
||||
axios.post(this.URL + `author/${this.author.id}/Book/${this.bookid}`)
|
||||
.then(() => {
|
||||
this.getAuthorBooks();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
removeBook(id){
|
||||
axios.delete(this.URL + `author/${this.author.id}/Book/${id}`)
|
||||
.then(() =>{
|
||||
this.getAuthorBooks();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header></Header>
|
||||
<main style="margin-top: 50pt;">
|
||||
<div class="container mt-4">
|
||||
<h1 class="text-center mb-4">Author Table:</h1>
|
||||
<button class="btn btn-success mr-2" @click="openModal(); author = new Object(); author.status = `create`">Добавить</button>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Имя:</th>
|
||||
<th>Фамилия:</th>
|
||||
<th>Фото:</th>
|
||||
<th>Реадактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="aut in authors" :key="aut.id">
|
||||
<td>{{ aut.firstname }}</td>
|
||||
<td>{{ aut.lastname }}</td>
|
||||
<td><img :src="aut.photo" class="img-thumbnail mw-50 mh-50"/></td>
|
||||
<td>
|
||||
<button class="btn btn-warning" @click="openModal(); author = Object.assign({}, aut); author.status = `edit`">Изменить</button>
|
||||
<button class="btn btn-danger" @click="deleteAuthor(aut.id)">Удалить</button>
|
||||
<button class="btn btn-primary" @click="author = aut; openManyToManyModal()">Книги</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
<div class="modal" tabindex="-1" id="editModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Author</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<label for="firstname">Имя:</label>
|
||||
<input type="text" class="form-control" id="firstname" name="firstname" v-model="author.firstname">
|
||||
<label for="lastname">Фамилия:</label>
|
||||
<input type="text" class="form-control" id="lastname" name="lastname" v-model="author.lastname">
|
||||
<label for="photo">Фотография:</label>
|
||||
<input class="form-control" type="file" id="photo" name="photo" @change="toBase64()">
|
||||
<img :src="author.photo" class="img-thumbnail"/>
|
||||
</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-success" v-if="author.status === `create`"
|
||||
@click="addAuthor">Создать</button>
|
||||
<button type="button" class="btn btn-primary" v-else
|
||||
@click="updateAuthor(author)">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" tabindex="-1" id="manyToManyModal">
|
||||
<div class="modal-dialog modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add Books to Author</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Название:</th>
|
||||
<th>Дата релиза:</th>
|
||||
<th>Обложка:</th>
|
||||
<th>Реадактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="bk in authorBooks" :key="bk.id">
|
||||
<td>{{ bk.name }}</td>
|
||||
<td>{{ bk.release }}</td>
|
||||
<td><img :src="bk.cover" class="img-thumbnail mw-50 mh-50"/></td>
|
||||
<td>
|
||||
<button class="btn btn-primary" type="button" @click="removeBook(bk.id)">Удалить</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="input-group mb-3">
|
||||
<select class="form-select" v-model="bookid">
|
||||
<option v-for="sbk in allBooks" :key="sbk.id" :value="sbk.id">{{ sbk.name }}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" type="button" @click="addBook()">Добавить</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="editModal" @click="closeManyToManyModal()">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
239
src/main/resources/frontend/spa-vue/src/pages/Books.vue
Normal file
239
src/main/resources/frontend/spa-vue/src/pages/Books.vue
Normal file
@ -0,0 +1,239 @@
|
||||
<script>
|
||||
import 'axios';
|
||||
import axios from "axios";
|
||||
import Header from '../components/Header.vue';
|
||||
import Footer from '../components/Footer.vue';
|
||||
import Book from '../models/Book';
|
||||
export default{
|
||||
components:{
|
||||
Header,
|
||||
Footer
|
||||
},
|
||||
created(){
|
||||
this.getBooks();
|
||||
},
|
||||
mounted() {
|
||||
const addModal = document.getElementById('editModal');
|
||||
addModal.addEventListener('shown.bs.modal', function () {
|
||||
})
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
books: [],
|
||||
bookGenres: [],
|
||||
allGenres: [],
|
||||
genreid: 0,
|
||||
URL: "http://localhost:8080/",
|
||||
book: new Book(),
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getBooks(){
|
||||
axios.get(this.URL + "book")
|
||||
.then(response => {
|
||||
this.books = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
async addBook(){
|
||||
await this.toBase64();
|
||||
console.log(this.book);
|
||||
axios.post(this.URL + "book", this.book)
|
||||
.then(() => {
|
||||
this.getBooks();
|
||||
this.closeModal();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
deleteBook(id){
|
||||
axios.delete(this.URL + `book/${id}`)
|
||||
.then(() =>{
|
||||
this.getBooks();
|
||||
})
|
||||
},
|
||||
async updateBook(book){
|
||||
if(book.cover === undefined) await this.toBase64();
|
||||
axios.put(this.URL + `book/${book.id}`, this.book)
|
||||
.then(() =>{
|
||||
this.getBooks();
|
||||
})
|
||||
this.closeModal();
|
||||
},
|
||||
openModal() {
|
||||
document.getElementById("editModal").style.display = "block";
|
||||
},
|
||||
openManyToManyModal(){
|
||||
this.getBookGenres();
|
||||
this.getAllGenres();
|
||||
document.getElementById("manyToManyModal").style.display = "block";
|
||||
},
|
||||
closeModal() {
|
||||
document.getElementById("editModal").style.display = "none";
|
||||
},
|
||||
closeManyToManyModal() {
|
||||
document.getElementById("manyToManyModal").style.display = "none";
|
||||
},
|
||||
async toBase64(){
|
||||
var file = document.getElementById("cover").files[0];
|
||||
var reader = new FileReader();
|
||||
var phototemp = this.book;
|
||||
reader.readAsDataURL(file);
|
||||
await new Promise((resolve, reject) => {
|
||||
reader.onload = function () {
|
||||
phototemp.cover = reader.result;
|
||||
console.log(phototemp);
|
||||
resolve();
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
console.log('Error: ', error);
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
},
|
||||
getAllGenres(){
|
||||
axios.get(this.URL + "genre")
|
||||
.then(response => {
|
||||
this.allGenres = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
getBookGenres(){
|
||||
axios.get(this.URL + `book/${this.book.id}/genres`)
|
||||
.then(response => {
|
||||
this.bookGenres = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
addGenre(){
|
||||
axios.post(this.URL + `book/${this.book.id}/Genre/${this.genreid}`)
|
||||
.then(() => {
|
||||
this.getBookGenres();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
removeGenre(id){
|
||||
axios.delete(this.URL + `book/${this.book.id}/Genre/${id}`)
|
||||
.then(() =>{
|
||||
this.getBookGenres();
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header></Header>
|
||||
<main style="margin-top: 50pt;">
|
||||
<div class="container mt-4">
|
||||
<h1 class="text-center mb-4">Book Table:</h1>
|
||||
<button class="btn btn-success mr-2" @click="openModal(); book = new Object(); book.status = `create`">Добавить</button>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Название:</th>
|
||||
<th>Дата релиза:</th>
|
||||
<th>Обложка:</th>
|
||||
<th>Реадактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="bk in books" :key="bk.id">
|
||||
<td>{{ bk.name }}</td>
|
||||
<td>{{ bk.release }}</td>
|
||||
<td><img :src="bk.cover" class="img-thumbnail mw-50 mh-50"/></td>
|
||||
<td>
|
||||
<button class="btn btn-warning" @click="openModal(); book = Object.assign({},bk); book.status = `edit`">Изменить</button>
|
||||
<button class="btn btn-danger" @click="deleteBook(bk.id)">Удалить</button>
|
||||
<button class="btn btn-primary" @click="book = bk; openManyToManyModal()">Жанры</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
<div class="modal" tabindex="-1" id="editModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Book</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="book.name">
|
||||
<label for="release">Дата релиза:</label>
|
||||
<input type="date" class="form-control" id="release" name="release" v-model="book.release">
|
||||
<label for="cover">Обложка:</label>
|
||||
<input class="form-control" type="file" id="cover" name="cover" @change="toBase64()">
|
||||
<img :src="book.cover" class="img-thumbnail"/>
|
||||
</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-success" v-if="book.status === `create`"
|
||||
@click="addBook">Создать</button>
|
||||
<button type="button" class="btn btn-primary" v-else
|
||||
@click="updateBook(book)">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal" tabindex="-1" id="manyToManyModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Add Genres to Book</h5>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Название:</th>
|
||||
<th>Реадактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="gen in bookGenres" :key="gen.id">
|
||||
<td>{{ gen.name }}</td>
|
||||
<td>
|
||||
<button class="btn btn-primary" type="button" @click="removeGenre(gen.id)">Удалить</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="input-group mb-3">
|
||||
<select class="form-select" v-model="genreid">
|
||||
<option v-for="sgen in allGenres" :key="sgen.id" :value="sgen.id">{{ sgen.name }}</option>
|
||||
</select>
|
||||
<button class="btn btn-outline-secondary" type="button" @click="addGenre()">Добавить</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="editModal" @click="closeManyToManyModal()">Закрыть</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
127
src/main/resources/frontend/spa-vue/src/pages/Genres.vue
Normal file
127
src/main/resources/frontend/spa-vue/src/pages/Genres.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<script>
|
||||
import 'axios';
|
||||
import axios from "axios";
|
||||
import Header from '../components/Header.vue';
|
||||
import Footer from '../components/Footer.vue';
|
||||
import Genre from '../models/Genre';
|
||||
export default{
|
||||
components:{
|
||||
Header,
|
||||
Footer
|
||||
},
|
||||
created(){
|
||||
this.getGenres();
|
||||
},
|
||||
mounted() {
|
||||
const addModal = document.getElementById('editModal');
|
||||
addModal.addEventListener('shown.bs.modal', function () {
|
||||
})
|
||||
},
|
||||
data(){
|
||||
return{
|
||||
genres: [],
|
||||
URL: "http://localhost:8080/",
|
||||
genre: new Genre(),
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
getGenres(){
|
||||
axios.get(this.URL + "genre")
|
||||
.then(response => {
|
||||
this.genres = response.data;
|
||||
console.log(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
addGenre(){
|
||||
console.log(this.genre);
|
||||
axios.post(this.URL + "genre", this.genre)
|
||||
.then(() => {
|
||||
this.getGenres();
|
||||
this.closeModal();
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
deleteGenre(id){
|
||||
axios.delete(this.URL + `genre/${id}`)
|
||||
.then(() =>{
|
||||
this.getGenres();
|
||||
})
|
||||
},
|
||||
updateGenre(genre){
|
||||
this.genre = genre;
|
||||
axios.put(this.URL + `genre/${genre.id}`, this.genre)
|
||||
.then(() =>{
|
||||
this.getGenres();
|
||||
})
|
||||
this.closeModal();
|
||||
},
|
||||
openModal() {
|
||||
document.getElementById("editModal").style.display = "block";
|
||||
},
|
||||
closeModal() {
|
||||
document.getElementById("editModal").style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Header></Header>
|
||||
<main style="margin-top: 50pt;">
|
||||
<div class="container mt-4">
|
||||
<h1 class="text-center mb-4">Genre Table:</h1>
|
||||
<button class="btn btn-success mr-2" @click="openModal(); genre = new Object(); genre.status = `create`">Добавить</button>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Название:</th>
|
||||
<th>Реадактировать запись:</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="gen in genres" :key="gen.id">
|
||||
<td>{{ gen.name }}</td>
|
||||
<td>
|
||||
<button class="btn btn-warning" @click="openModal(); genre = Object.assign({},gen); genre.status = `edit`">Изменить</button>
|
||||
<button class="btn btn-danger" @click="deleteGenre(gen.id)">Удалить</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main>
|
||||
<div class="modal" tabindex="-1" id="editModal">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Genre</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="genre.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-success" v-if="genre.status === `create`"
|
||||
@click="addGenre">Создать</button>
|
||||
<button type="button" class="btn btn-primary" v-else
|
||||
@click="updateGenre(genre)">Сохранить</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -1,8 +1,14 @@
|
||||
import {createRouter, createWebHistory} from "vue-router"
|
||||
import Index from '../pages/Index.vue'
|
||||
import Authors from '../pages/Authors.vue'
|
||||
import Books from '../pages/Books.vue'
|
||||
import Genres from '../pages/Genres.vue'
|
||||
|
||||
const routes = [
|
||||
{path: '/', component: Index},
|
||||
{path: '/authors', component: Authors},
|
||||
{path: '/books', component: Books},
|
||||
{path: '/genres', component: Genres},
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
|
Loading…
Reference in New Issue
Block a user