Lab4 is done

This commit is contained in:
Katerina881 2023-04-04 12:03:56 +04:00
parent 00c99afbcf
commit 2224416988
19 changed files with 362 additions and 515 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
/frontend/node_modules/ /frontend/node_modules/
/build
/.idea

9
frontend/node_modules/fs/README.md generated vendored
View File

@ -1,9 +0,0 @@
# Security holding package
This package name is not currently in use, but was formerly occupied
by another package. To avoid malicious use, npm is hanging on to the
package name, but loosely, and we'll probably give it to you if you
want it.
You may adopt this package by contacting support@npmjs.com and
requesting the name.

View File

@ -1,46 +0,0 @@
{
"_from": "fs",
"_id": "fs@0.0.1-security",
"_inBundle": false,
"_integrity": "sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==",
"_location": "/fs",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "fs",
"name": "fs",
"escapedName": "fs",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/fs/-/fs-0.0.1-security.tgz",
"_shasum": "8a7bd37186b6dddf3813f23858b57ecaaf5e41d4",
"_spec": "fs",
"_where": "C:\\Users\\user\\Desktop\\something\\frontend",
"author": "",
"bugs": {
"url": "https://github.com/npm/security-holder/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "This package name is not currently in use, but was formerly occupied by another package. To avoid malicious use, npm is hanging on to the package name, but loosely, and we'll probably give it to you if you want it.",
"homepage": "https://github.com/npm/security-holder#readme",
"keywords": [],
"license": "ISC",
"main": "index.js",
"name": "fs",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/security-holder.git"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "0.0.1-security"
}

View File

@ -1,9 +0,0 @@
# Security holding package
This package name is not currently in use, but was formerly occupied
by another package. To avoid malicious use, npm is hanging on to the
package name, but loosely, and we'll probably give it to you if you
want it.
You may adopt this package by contacting support@npmjs.com and
requesting the name.

View File

@ -1,39 +0,0 @@
{
"_from": "http",
"_id": "http@0.0.1-security",
"_inBundle": false,
"_integrity": "sha512-RnDvP10Ty9FxqOtPZuxtebw1j4L/WiqNMDtuc1YMH1XQm5TgDRaR1G9u8upL6KD1bXHSp9eSXo/ED+8Q7FAr+g==",
"_location": "/http",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "http",
"name": "http",
"escapedName": "http",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/http/-/http-0.0.1-security.tgz",
"_shasum": "3aac09129d12dc2747bbce4157afde20ad1f7995",
"_spec": "http",
"_where": "C:\\Users\\user\\Desktop\\something\\frontend",
"bugs": {
"url": "https://github.com/npm/security-holder/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "security holding package",
"homepage": "https://github.com/npm/security-holder#readme",
"name": "http",
"repository": {
"type": "git",
"url": "git+https://github.com/npm/security-holder.git"
},
"version": "0.0.1-security"
}

View File

@ -1,11 +1,11 @@
{ {
"name": "lab4_vue_front", "name": "front",
"version": "0.1.0", "version": "0.1.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "lab4_vue_front", "name": "front",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@popperjs/core": "^2.11.7", "@popperjs/core": "^2.11.7",

View File

@ -1,5 +1,5 @@
{ {
"name": "lab4_vue_front", "name": "front",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {

View File

@ -1,20 +1,44 @@
<template> <template>
<div class="nav"> <div class="nav row">
<div class="nav-center"> <div class="nav-left col-10">
<router-link to="/customers" class="button primary clear">Профили</router-link> <router-link to="/customers" class="button primary clear">Профили</router-link>
<router-link to="/posts" class="button primary clear">Посты</router-link> <router-link to="/posts" class="button primary clear">Посты</router-link>
<router-link to="/comments" class="button primary clear">Комментарии</router-link> </div>
</div>" <div class="nav-right col-2">
<select class="form-select" style="font-size: 16px;" v-model="currentCustomerId">
<option value="-1" selected class="button dark outline" :on-click="updateCurrentCustomer()">Не выбран</option>
<option v-for="customer in customers" v-bind:value="customer['id']" class="button dark outline" :on-click="updateCurrentCustomer()">{{ customer['username'] }}</option>
</select>
</div>
</div> </div>
<router-view></router-view> <router-view></router-view>
</template> </template>
<script> <script>
import axios from 'axios'
export default { export default {
data() { data() {
return {} return {
} currentCustomerId: -1,
customers: []
}
},
methods: {
async updateCurrentCustomer() {
history.replaceState(this.currentCustomerId, "");
}
},
async beforeMount() {
setInterval(async () => {
const response = await axios.get('http://localhost:8080/customer');
this.customers = [];
response.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
}, 500)
},
} }
</script> </script>

View File

@ -1,194 +0,0 @@
<template>
<div class="row">
<div class="col">
<div class="row mb-5">
<p class='is-center h2'>Комментарии</p>
</div>
<div class="row mb-5">
<div class="col"></div>
<div class="col-3">
<div class="dropdown row">
<button class="button secondary outline dropdown-toggle mb-5" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ selectedCustomerUsername }}
</button>
<ul class="dropdown-menu" >
<li v-for="customer in customers">
<a class="dropdown-item button secondary outline" href="#" v-on:click="getSelectedCustomer(customer)">
{{ customer['username'] }}
</a>
</li>
</ul>
</div>
</div>
<div class="col"></div>
</div>
<div v-if="selectedCustomerId != 0">
<div v-if="!(posts.length == 0)" class="row">
<div class="col">
<div class="row mb-5 card" v-for="post in posts">
<div class="col">
<div class="row is-left h3"><p>Автор: <span class="text-primary">{{ post['customerName'] }}</span></p></div>
<div class="row text-center">
<span class="h1">{{ post['title'] }}</span>
</div>
<div class="row text-center mb-5">
<span class="h3">{{ post['content'] }}</span>
</div>
<div class="row">
<div class="col">
<p class="row h2 is-center mb-3">Комментарии</p>
<div v-if="!(post['comments'].length == 0)" class="row text-left mb-5 card" v-for="comment in post['comments']">
<div class="row mb-1">
<span class="h2 text-primary">{{ comment['customerName'] }}</span>
</div>
<div class="row mb-3">
<span class="h3">{{ comment['content'] }}</span>
</div>
<div v-if="selectedCustomerContainsComment(comment) == true" class="row">
<button v-on:click="selectedCommentId = comment['id']; selectedPostTitle = post['title']" class="button primary outline col" data-bs-toggle="modal" data-bs-target="#commentEdit">Изменить комментарий</button>
<button v-on:click="deleteComment(comment['id'])" class="button error col">Удалить комментарий</button>
</div>
</div>
<p v-else class="h3 row is-center mb-1">Пусто</p>
<div class="row">
<button type="button" v-on:click="selectedPostId = post['id']; selectedPostTitle = post['title'];" class="button secondary outline" data-bs-toggle="modal" data-bs-target="#commentCreate">Добавить комментарий</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-else class="row text-center is-center">
Нет постов
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="commentCreate" tabindex="-1" role="dialog" aria-labelledby="commentCreateLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="commentCreateLabel">Создать комментарий</h5>
</div>
<div class="modal-body text-center">
<p>Под именем:</p>
<p>{{ selectedCustomerUsername }}</p>
<p>К посту:</p>
<p>{{ selectedPostTitle }}</p>
<p>Комментарий</p>
<textarea v-model='contentModal' id="createModalText" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='createComment'>Создать</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="commentEdit" tabindex="-1" role="dialog" aria-labelledby="commentEditLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="commentEditLabel">Изменить комментарий</h5>
</div>
<div class="modal-body text-center">
<p>Под именем:</p>
<p>{{ selectedCustomerUsername }}</p>
<p>К посту:</p>
<p>{{ selectedPostTitle }}</p>
<p>Комментарий</p>
<textarea v-model='contentModal' id="editModalText" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='editComment'>Изменить</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
customers: [],
selectedCustomerId: 0,
selectedCustomerUsername: 'Профиль не выбран',
posts: [],
selectedPostId: 0,
selectedPostTitle: '',
contentModal: '',
selectedCommentId: 0
}
},
methods: {
getSelectedCustomer(customer){
this.selectedCustomerId = customer['id'];
this.selectedCustomerUsername = customer['username'];
this.refreshList();
},
selectedCustomerContainsComment(comment) {
var customer = this.customers.find(element => element['id'] == this.selectedCustomerId);
console.log(customer);
if (customer == null) return false;
var flag = false;
customer['comments'].forEach(commentIn => {
if (commentIn['id'] == comment['id']) {
flag = true;
}
});
return flag;
},
async createComment() {
await axios.post('http://localhost:8080/comment?text=' + this.contentModal + '&ownerId=' + this.selectedCustomerId + '&postId=' + this.selectedPostId);
this.refreshList();
},
async deleteComment(commentId) {
await axios.delete('http://localhost:8080/comment/' + commentId);
this.refreshList();
},
async editComment(){
await axios.put('http://localhost:8080/comment/' + this.selectedCommentId + '?text=' + this.contentModal);
this.refreshList();
},
async refreshList(){
this.customers = [];
this.posts = [];
const responseCustomer = await axios.get('http://localhost:8080/customer');
responseCustomer.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
const responsePost = await axios.get('http://localhost:8080/post');
responsePost.data.forEach(element => {
this.posts.push(element);
console.log(element);
});
}
},
async beforeMount() {
const responseCustomer = await axios.get('http://localhost:8080/customer');
responseCustomer.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
const responsePost = await axios.get('http://localhost:8080/post');
responsePost.data.forEach(element => {
this.posts.push(element);
console.log(element);
});
}
}
</script>
<style lang="">
</style>

View File

@ -42,7 +42,7 @@
</div> </div>
</div> </div>
<p v-else class="row">Нет постов</p> <p v-else class="row">Нет постов</p>
<div class="row"> <div class="row" v-if="customer['id'] == currentCustomerId">
<button v-on:click="deleteUser(customer['id'])" class="col button dark outline">Удалить</button> <button v-on:click="deleteUser(customer['id'])" class="col button dark outline">Удалить</button>
<button v-on:click="selectedCustomer = customer; usernameModal=customer['username'];passwordModal=customer['password']" class="col button primary outline" data-bs-toggle="modal" data-bs-target="#customerEdit">Редактировать</button> <button v-on:click="selectedCustomer = customer; usernameModal=customer['username'];passwordModal=customer['password']" class="col button primary outline" data-bs-toggle="modal" data-bs-target="#customerEdit">Редактировать</button>
</div> </div>
@ -104,6 +104,7 @@ export default {
usernameModal: '', usernameModal: '',
passwordModal: '', passwordModal: '',
selectedCustomer: {}, selectedCustomer: {},
currentCustomerId: -1
} }
}, },
methods: { methods: {
@ -120,22 +121,41 @@ export default {
this.refreshList(); this.refreshList();
}, },
async refreshList() { async refreshList() {
const response = await axios.get('http://localhost:8080/customer');
this.customers = []; this.customers = [];
if (this.$route.params.id === "") {
const response = await axios.get('http://localhost:8080/customer');
response.data.forEach(element => { response.data.forEach(element => {
this.customers.push(element); this.customers.push(element);
console.log(element); console.log(element);
}); });
} else {
const response = await axios.get('http://localhost:8080/customer/' + this.$route.params.id);
this.customers.push(response.data)
} }
}, },
async beforeMount() {
const response = await axios.get('http://localhost:8080/customer');
response.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
} },
async mounted() {
this.currentCustomerId = history.state;
setInterval(async () => this.currentCustomerId = history.state, 50)
if (this.$route.params.id === "") {
const response = await axios.get('http://localhost:8080/customer');
response.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
} else {
const response = await axios.get('http://localhost:8080/customer/' + this.$route.params.id);
this.customers.push(response.data)
}
},
async beforeRouteUpdate(to, from) {
this.$route.params.id = to.params.id;
this.refreshList();
},
} }
</script> </script>

View File

@ -1,188 +0,0 @@
<template>
<div class="row">
<div class="col">
<div class="row mb-5">
<p class='is-center h2'>Посты</p>
</div>
<div class="row mb-5">
<div class="col"></div>
<div class="col-3">
<div class="dropdown row">
<button class="button secondary outline dropdown-toggle mb-5" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{ selectedCustomer }}
</button>
<ul class="dropdown-menu" >
<li v-for="customer in customers">
<a class="dropdown-item button secondary outline" href="#" v-on:click="getSelectedCustomer(customer)">
{{ customer['username'] }}
</a>
</li>
</ul>
</div>
<div class="row">
<button type='button' class="button primary" data-bs-toggle="modal" data-bs-target="#postCreate">
Добавить новый пост
</button>
</div>
</div>
<div class="col"></div>
</div>
<div class="row text-center">
<p class='h2 mb-5'>Список постов пользователя {{ selectedCustomer }}</p>
</div>
<div v-if="!(posts.length == 0)" class="row">
<div class="col">
<div class="row mb-4 card" v-for="post in posts">
<div class="col">
<div class="row text-center">
<span class="h1">{{ post['title'] }}</span>
</div>
<div class="row text-center">
<span class="h3">{{ post['content'] }}</span>
</div>
<br class="row" />
<div class="row">
<div class="col">
<p class="row h2 is-center mb-3">Комментарии</p>
<div v-if="!(post['comments'].length == 0)" class="row text-left mb-5 card" v-for="comment in post['comments']">
<div class="row mb-3">
<span class="h2 text-primary">{{ comment['customerName'] }}</span>
</div>
<div class="row">
<span class="h3">{{ comment['content'] }}</span>
</div>
</div>
<p v-else class="h3 row is-center">Пусто</p>
</div>
</div>
<br class="row" />
<div class="row">
<button type="button" v-on:click="deletePost(post['id'])" class="col button dark outline">Удалить пост</button>
<button type="button" v-on:click="selectedPostId = post['id']" class="col button primary outline" data-bs-toggle="modal" data-bs-target="#postEdit">Изменить пост</button>
</div>
</div>
</div>
</div>
</div>
<div v-else class="row text-center is-center">
Нет постов
</div>
</div>
</div>
<div class="modal fade" id="postCreate" tabindex="-1" role="dialog" aria-labelledby="postCreateLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="postCreateLabel">Создать пост</h5>
</div>
<div class="modal-body text-center">
<p>Пользователь:</p>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle ms-3 mb-3" type="button" data-bs-toggle="dropdown" aria-expanded="false">
{{selectedCustomer}}
</button>
<ul class="dropdown-menu" >
<li v-for="customer in customers">
<a class="dropdown-item" href="#" v-on:click="getSelectedCustomer(customer)">
{{ customer['username'] }}
</a>
</li>
</ul>
</div>
<p>Заголовок:</p>
<textarea v-model='titleModal' id="modalText" cols="30" rows="1"></textarea>
<p>Содержание:</p>
<textarea v-model='contentModal' id="modalText" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='createPost'>Сохранить</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="postEdit" tabindex="-1" role="dialog" aria-labelledby="postEditLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="postEditLabel">Редактировать пост</h5>
</div>
<div class="modal-body text-center">
<p>{{ selectedCustomer }}</p>
<p>Заголовок</p>
<textarea v-model='titleModal' id="editModalTitle" cols="30" rows="1"></textarea>
<p>Содержание</p>
<textarea v-model='contentModal' id="editModalContent" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='editPost'>Изменить</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
customers: [],
selectedCustomerId: 0,
selectedCustomer: 'Профиль не выбран',
posts: [],
titleModal: '',
contentModal: '',
selectedPostId: 0,
}
},
methods: {
async getSelectedCustomer(customer){
this.selectedCustomerId = customer['id'];
this.selectedCustomer = customer['username'];
this.posts = customer['posts'];
},
async createPost() {
const response = await axios.post('http://localhost:8080/post?title=' + this.titleModal + '&content=' + this.contentModal + '&authorId=' + this.selectedCustomerId);
this.refreshList();
},
async deletePost(postId) {
const response = await axios.delete('http://localhost:8080/post/' + postId);
this.refreshList();
},
async editPost(){
const response = await axios.put('http://localhost:8080/post/' + this.selectedPostId + '?title=' + this.titleModal + '&content=' + this.contentModal);
this.refreshList();
},
async refreshList() {
const response = await axios.get('http://localhost:8080/customer');
this.customers = [];
response.data.forEach(element => {
this.customers.push(element);
if (element['id'] == this.selectedCustomerId) {
this.selectedCustomerUsername = element['username'];
this.posts = element['posts'];
}
console.log(element);
});
this.textModal = '';
}
},
async beforeMount() {
const response = await axios.get('http://localhost:8080/customer');
response.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
}
}
</script>
<style lang="">
</style>

View File

@ -0,0 +1,227 @@
<template>
<div class="row">
<div class="col">
<div class="row mb-5">
<p class='is-center h2'>Посты</p>
</div>
<div class="row mb-5" v-if="currentCustomerId != -1">
<div class="col"></div>
<div class="col-10">
<div class="row mb-4 is-center">
<p class="col-2 is-left mb-2">Заголовок:</p>
<input type="text" class="col-6" v-model="titleModal"/>
</div>
<div class="row mb-4 is-center">
<p class="col-2 is-left mb-2">Текст:</p>
<textarea type="textarea" class="col-6" v-model="postContentModal"/>
</div>
<div class="row is-center">
<button type='button' class="button primary col-8" v-on:click='createPost'>
Опубликовать
</button>
</div>
</div>
<div class="col"></div>
</div>
<div v-if="!(posts.length == 0)" class="row">
<div class="col">
<div class="row mb-5 card" v-for="post in posts">
<div class="col">
<div class="row h3">
<div class="col is-left">
<p>Автор: <router-link v-bind:to="'/customers/' + post['customerId']" class="text-primary">{{ post['customerName'] }}</router-link></p>
</div>
<div class="col is-right">
<p>Дата: <span class="text-primary">{{ post['createDate'] }}</span></p>
</div>
</div>
<div class="row text-center">
<span class="h1">{{ post['title'] }}</span>
</div>
<div class="row text-center mb-5">
<span class="h3">{{ post['content'] }}</span>
</div>
<div class="row">
<div class="col">
<p class="row h2 is-center mb-3">Комментарии</p>
<div v-if="!(post['comments'].length == 0)" class="row text-left mb-5 card" v-for="comment in post['comments']">
<div class="row mb-1">
<div class="col is-left">
<span class="h2 text-primary">{{ comment['customerName'] }}</span>
</div>
<div class="col is-right">
<span class="h2 text-primary">{{ comment['createDate'] }}</span>
</div>
</div>
<div class="row mb-3">
<span class="h3">{{ comment['content'] }}</span>
</div>
<div v-if="selectedCustomerContainsComment(comment) == true" class="row">
<button v-on:click="selectedCommentId = comment['id']; selectedPostTitle = post['title']" class="button primary outline col" data-bs-toggle="modal" data-bs-target="#commentEdit">Изменить комментарий</button>
<button v-on:click="deleteComment(comment['id'])" class="button error col">Удалить комментарий</button>
</div>
</div>
<p v-else class="h3 row is-center mb-5">Пусто</p>
<div class="row" v-if="currentCustomerId != -1">
<input type="text" v-bind:id="'post-comment-' + post['id']" class="col-9"/>
<button type="button" v-on:click="selectedPostId = post['id']; selectedPostTitle = post['title']; createComment()" class="button col-3 secondary outline">Комментировать</button>
</div>
</div>
</div>
<div class="row" v-if="post['customerId'] == currentCustomerId">
<button type="button" v-on:click="deletePost(post['id'])" class="col button dark outline">Удалить пост</button>
<button type="button" v-on:click="selectedPostId = post['id']" class="col button primary outline" data-bs-toggle="modal" data-bs-target="#postEdit">Изменить пост</button>
</div>
</div>
</div>
</div>
</div>
<div v-else class="row text-center is-center">
Нет постов
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="commentEdit" tabindex="-1" role="dialog" aria-labelledby="commentEditLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="commentEditLabel">Изменить комментарий</h5>
</div>
<div class="modal-body text-center">
<p>Под именем:</p>
<p>{{ currentCustomer['username'] }}</p>
<p>К посту:</p>
<p>{{ selectedPostTitle }}</p>
<p>Комментарий</p>
<textarea v-model='contentModal' id="editModalText" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='editComment'>Изменить</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="postEdit" tabindex="-1" role="dialog" aria-labelledby="postEditLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="postEditLabel">Редактировать пост</h5>
</div>
<div class="modal-body text-center">
<p>{{ currentCustomer['username'] }}</p>
<p>Заголовок</p>
<textarea v-model='titleModal' id="editModalTitle" cols="30" rows="1"></textarea>
<p>Содержание</p>
<textarea v-model='postContentModal' id="editModalPostContent" cols="30" rows="1"></textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" v-on:click='editPost'>Изменить</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
customers: [],
selectedCustomerId: 0,
currentCustomer: {},
posts: [],
selectedPostId: 0,
selectedPostTitle: '',
contentModal: '',
titleModal: '',
postContentModal: '',
selectedCommentId: 0,
currentCustomerId: -1,
}
},
methods: {
selectedCustomerContainsComment(comment) {
var customer = this.customers.find(element => element['id'] == this.currentCustomerId);
console.log(customer);
if (customer == null) return false;
var flag = false;
customer['comments'].forEach(commentIn => {
if (commentIn['id'] == comment['id']) {
flag = true;
}
});
return flag;
},
async createComment() {
const content = document.getElementById("post-comment-" + this.selectedPostId).value
await axios.post('http://localhost:8080/comment?text=' + content + '&ownerId=' + this.currentCustomerId + '&postId=' + this.selectedPostId);
document.getElementById("post-comment-" + this.selectedPostId).value = ''
this.refreshList();
},
async deleteComment(commentId) {
await axios.delete('http://localhost:8080/comment/' + commentId);
this.refreshList();
},
async editComment(){
await axios.put('http://localhost:8080/comment/' + this.selectedCommentId + '?text=' + this.contentModal);
this.refreshList();
},
async createPost() {
const response = await axios.post('http://localhost:8080/post?title=' + this.titleModal + '&content=' + this.postContentModal + '&authorId=' + this.currentCustomerId);
this.titleModal = ''
this.postContentModal = ''
this.refreshList();
},
async deletePost(postId) {
const response = await axios.delete('http://localhost:8080/post/' + postId);
this.refreshList();
},
async editPost(){
const response = await axios.put('http://localhost:8080/post/' + this.selectedPostId + '?title=' + this.titleModal + '&content=' + this.postContentModal);
this.refreshList();
},
async refreshList(){
this.customers = [];
this.posts = [];
const responseCustomer = await axios.get('http://localhost:8080/customer');
responseCustomer.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
const responsePost = await axios.get('http://localhost:8080/post');
responsePost.data.forEach(element => {
this.posts.splice(0, 0, element);
console.log(element);
});
}
},
async beforeMount() {
this.currentCustomerId = history.state;
setInterval(async () => this.currentCustomerId = history.state, 50)
const responseCustomer = await axios.get('http://localhost:8080/customer');
responseCustomer.data.forEach(element => {
this.customers.push(element);
if (element['id'] == this.currentCustomerId) {
this.currentCustomer = element;
}
console.log(element);
});
const responsePost = await axios.get('http://localhost:8080/post');
responsePost.data.forEach(element => {
this.posts.splice(0, 0, element);
console.log(element);
});
}
}
</script>
<style lang="">
</style>

View File

@ -2,22 +2,21 @@ import {createApp} from 'vue'
import App from './App' import App from './App'
import { createRouter, createWebHistory } from "vue-router" import { createRouter, createWebHistory } from "vue-router"
import Customer from './components/Customer' import Customers from './components/Customers'
import Post from './components/Post' import Posts from './components/Posts'
import Comment from './components/Comment'
const routes = [ const routes = [
{ {
path: '/customers', path: '/customers/:id?',
component: Customer name: "Customers",
component: Customers,
props: true
}, },
{ {
path: '/posts', path: '/posts',
component: Post name: "Posts",
}, component: Posts,
{ props: true
path: '/comments',
component: Comment
} }
] ]

View File

@ -2,12 +2,18 @@ package np.something.DTO;
import np.something.model.Comment; import np.something.model.Comment;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class CommentDto { public class CommentDto {
public final long id; public final long id;
public final String content; public final String content;
public final String customerName; public final String customerName;
public final String postTitle; public final String postTitle;
public final String postAuthor; public final String postAuthor;
public final long postAuthorId;
public final String createDate;
public CommentDto(Comment comment) { public CommentDto(Comment comment) {
this.id = comment.getId(); this.id = comment.getId();
@ -15,6 +21,8 @@ public class CommentDto {
this.customerName = comment.getCustomer().getUsername(); this.customerName = comment.getCustomer().getUsername();
this.postTitle = comment.getPost().getTitle(); this.postTitle = comment.getPost().getTitle();
this.postAuthor = comment.getPost().getCustomer().getUsername(); this.postAuthor = comment.getPost().getCustomer().getUsername();
this.postAuthorId = comment.getPost().getCustomer().getId();
this.createDate = comment.getCreateDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} }
public long getId() { public long getId() {
@ -34,4 +42,12 @@ public class CommentDto {
public String getPostAuthor() { public String getPostAuthor() {
return postAuthor; return postAuthor;
} }
public long getPostAuthorId() {
return postAuthorId;
}
public String getCreateDate() {
return createDate;
}
} }

View File

@ -2,6 +2,8 @@ package np.something.DTO;
import np.something.model.Post; import np.something.model.Post;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List; import java.util.List;
public class PostDto { public class PostDto {
@ -9,14 +11,20 @@ public class PostDto {
public final String title; public final String title;
public final String content; public final String content;
public final String customerName; public final String customerName;
public final long customerId;
public final List<CommentDto> comments; public final List<CommentDto> comments;
public String createDate;
public PostDto(Post post) { public PostDto(Post post) {
this.id = post.getId(); this.id = post.getId();
this.title = post.getTitle(); this.title = post.getTitle();
this.content = post.getContent(); this.content = post.getContent();
this.customerName = post.getCustomer().getUsername(); this.customerName = post.getCustomer().getUsername();
this.customerId = post.getCustomer().getId();
this.comments = post.getComments().stream().map(CommentDto::new).toList(); this.comments = post.getComments().stream().map(CommentDto::new).toList();
this.createDate = post.getCreateDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
} }
public long getId() { public long getId() {
@ -38,4 +46,12 @@ public class PostDto {
public List<CommentDto> getComments() { public List<CommentDto> getComments() {
return comments; return comments;
} }
public long getCustomerId() {
return customerId;
}
public String getCreateDate() {
return createDate;
}
} }

View File

@ -3,6 +3,7 @@ package np.something.model;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.Objects; import java.util.Objects;
@Entity @Entity
@ -23,6 +24,9 @@ public class Comment {
@JoinColumn(name="post_fk") @JoinColumn(name="post_fk")
private Post post; private Post post;
@Column(columnDefinition = "timestamp default NOW()")
private LocalDateTime createDate;
public Comment() { public Comment() {
} }
@ -67,4 +71,12 @@ public class Comment {
public int hashCode() { public int hashCode() {
return Objects.hash(id); return Objects.hash(id);
} }
public LocalDateTime getCreateDate() {
return createDate;
}
public void setCreateDate(LocalDateTime createDate) {
this.createDate = createDate;
}
} }

View File

@ -3,6 +3,7 @@ package np.something.model;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -27,6 +28,9 @@ public class Post {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "post", cascade = CascadeType.ALL) @OneToMany(fetch = FetchType.EAGER, mappedBy = "post", cascade = CascadeType.ALL)
private List<Comment> comments; private List<Comment> comments;
@Column(columnDefinition = "timestamp default NOW()")
private LocalDateTime createDate;
public Post() { public Post() {
} }
@ -80,4 +84,12 @@ public class Post {
public Long getId() { public Long getId() {
return id; return id;
} }
public LocalDateTime getCreateDate() {
return createDate;
}
public void setCreateDate(LocalDateTime createDate) {
this.createDate = createDate;
}
} }

View File

@ -9,6 +9,7 @@ import np.something.repositories.CommentRepository;
import np.something.util.validation.ValidatorUtil; import np.something.util.validation.ValidatorUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@ -37,6 +38,7 @@ public class CommentService {
@Transactional @Transactional
public Comment addComment(Customer customer, Post post, String content) { public Comment addComment(Customer customer, Post post, String content) {
final Comment comment = new Comment(customer, post, content); final Comment comment = new Comment(customer, post, content);
comment.setCreateDate(LocalDateTime.now());
validatorUtil.validate(comment); validatorUtil.validate(comment);
customer.getComments().add(comment); customer.getComments().add(comment);
post.getComments().add(comment); post.getComments().add(comment);

View File

@ -14,6 +14,7 @@ import np.something.util.validation.ValidatorUtil;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@Service @Service
@ -40,6 +41,7 @@ public class PostService {
@Transactional @Transactional
public Post addPost(Customer customer, String title, String content) { public Post addPost(Customer customer, String title, String content) {
Post post = new Post(customer, title, content); Post post = new Post(customer, title, content);
post.setCreateDate(LocalDateTime.now());
validatorUtil.validate(post); validatorUtil.validate(post);
customer.getPosts().add(post); customer.getPosts().add(post);
return postRepository.save(post); return postRepository.save(post);