Frontend is finished(I think)

This commit is contained in:
Сергей Полевой 2023-04-04 00:34:13 +04:00
parent cbf4b0b9a3
commit 00c99afbcf
23 changed files with 18428 additions and 137 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/frontend/node_modules/

17
frontend/README.md Normal file
View File

@ -0,0 +1,17 @@
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
frontend/babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@ -1,65 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Calculator</title>
<link rel="stylesheet" href="https://unpkg.com/chota@latest">
</head>
<body>
<div class="container" style="max-width:600px">
<div class="card row is-full-screen is-center">
<div class="col">
<div class="row">
<div class="col">
<input type="text" id="value1">
</div>
<div class="col">
<select id="operation">
<option value="sum" selected>+</option>
<option value="sub">-</option>
<option value="mul">*</option>
<option value="invert">~</option>
</select>
</div>
<div class="col">
<input type="text" id="value2">
</div>
</div>
<div class="row">
<div class="col">
<button type="button" id="get-int-result" onclick="calculate('intops')">Result for int</button>
</div>
<div class="col is-right">
<button type="button" id="get-string-result" onclick="calculate('stringops')">Result for string</button>
</div>
</div>
<div class="card row is-center">
<h5 class="is-center" id="result"></h5>
</div>
</div>
</div>
</div>
<script>
async function calculate(ops) {
const value1 = document.getElementById("value1").value
const value2 = document.getElementById("value2").value
const op = document.getElementById("operation").value
if (op == 'sum') {
document.getElementById("result").innerHTML = await (await fetch(`http://127.0.0.1:8080/sum?value1=${value1}&value2=${value2}&ops=${ops}`)).text()
} else if (op == 'sub') {
document.getElementById("result").innerHTML = await (await fetch(`http://127.0.0.1:8080/sub?value1=${value1}&value2=${value2}&ops=${ops}`)).text()
} else if (op == 'mul') {
document.getElementById("result").innerHTML = await (await fetch(`http://127.0.0.1:8080/mul?value=${value1}&count=${value2}&ops=${ops}`)).text()
} else {
document.getElementById("result").innerHTML = await (await fetch(`http://127.0.0.1:8080/invert?value=${value1}&ops=${ops}`)).text()
}
}
</script>
</body>
</html>

View File

@ -1,12 +0,0 @@
const fs = require('fs')
const http = require('http')
const requestListener = async function (req, res) {
res.writeHead(200);
fs.readFile('index.html', 'utf8', (err, data) => {
res.end(data);
});
};
const server = http.createServer(requestListener)
server.listen(5050)

19
frontend/jsconfig.json Normal file
View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

17567
frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,29 @@
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"name": "lab4_vue_front",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "node index.js"
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"author": "",
"license": "ISC",
"dependencies": {
"fs": "0.0.1-security",
"http": "0.0.1-security"
}
"@popperjs/core": "^2.11.7",
"axios": "^1.3.4",
"core-js": "^3.8.3",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/chota@latest">
<title>Социальная сеть</title>
</head>
<body class="container">
<script src="https://unpkg.com/@popperjs/core@2"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3" crossorigin="anonymous"></script>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

23
frontend/src/App.vue Normal file
View File

@ -0,0 +1,23 @@
<template>
<div class="nav">
<div class="nav-center">
<router-link to="/customers" 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>
<router-view></router-view>
</template>
<script>
export default {
data() {
return {}
}
}
</script>
<style lang="">
</style>

View File

@ -0,0 +1,194 @@
<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

@ -0,0 +1,144 @@
<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-10 is-center">
<button class="button primary" data-bs-toggle="modal" data-bs-target="#customerCreate">
Добавить нового пользователя
</button>
</div>
<div class="col"></div>
</div>
<p class='h3 is-center row mb-5'>Список профилей</p>
<div class="row">
<div class="col">
<div v-for="customer in customers" class="row card mb-3">
<div class="row">
<div class="col is-left h3">ID: {{ customer['id'] }}</div>
<div class="col is-center h3">Никнейм: {{ customer['username'] }}</div>
<div class="col is-right h3">Пароль: {{ customer['password'] }}</div>
</div>
<p class="row">Комментарии:</p>
<div class="row" v-if="!(customer['comments'].length == 0)">
<div class="col">
<div v-for="comment in customer['comments']" class="row is-left card mb-3">
<div class="row is-left h4">"{{ comment['content'] }}" - к посту '{{ comment['postTitle'] }}' от пользователя {{ comment['postAuthor'] }}</div>
</div>
</div>
</div>
<p v-else class="row">Нет комментариев</p>
<p class="row">Посты: </p>
<div class="row" v-if="!(customer['posts'].length == 0)">
<div class="col">
<div v-for="post in customer['posts']" class="row is-left card mb-3">
<div class="row is-center h1">{{ post['title'] }}</div>
<div class="row is-left h3">{{ post['content'] }}</div>
</div>
</div>
</div>
<p v-else class="row">Нет постов</p>
<div class="row">
<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>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="customerCreate" tabindex="-1" role="dialog" aria-labelledby="customerCreateLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="customerCreateLabel">Создать профиль</h5>
</div>
<div class="modal-body text-center">
<p>Логин</p>
<textarea v-model='usernameModal' id="usernameText" cols="30" rows="1"></textarea>
<p>Пароль</p>
<textarea v-model='passwordModal' id="passwordText" 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='createUser'>Сохранить</button>
</div>
</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" id="customerEdit" tabindex="-1" role="dialog" aria-labelledby="customerEditLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="customerEditLabel">Редактировать профиль</h5>
</div>
<div class="modal-body text-center">
<p>Логин</p>
<textarea v-model='usernameModal' id="usernameText" cols="30" rows="1"></textarea>
<p>Пароль</p>
<textarea v-model='passwordModal' id="passwordText" 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='editUser'>Изменить</button>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data() {
return {
customers: [],
usernameModal: '',
passwordModal: '',
selectedCustomer: {},
}
},
methods: {
async createUser(){
const response = await axios.post('http://localhost:8080/customer?username=' + this.usernameModal + '&password=' + this.passwordModal);
this.refreshList();
},
async deleteUser(id) {
const response = await axios.delete('http://localhost:8080/customer/' + id);
this.refreshList();
},
async editUser() {
const response = await axios.put('http://localhost:8080/customer/' + this.selectedCustomer['id'] + '?username=' + this.usernameModal + '&password=' + this.passwordModal);
this.refreshList();
},
async refreshList() {
const response = await axios.get('http://localhost:8080/customer');
this.customers = [];
response.data.forEach(element => {
this.customers.push(element);
console.log(element);
});
}
},
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,188 @@
<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>

30
frontend/src/main.js Normal file
View File

@ -0,0 +1,30 @@
import {createApp} from 'vue'
import App from './App'
import { createRouter, createWebHistory } from "vue-router"
import Customer from './components/Customer'
import Post from './components/Post'
import Comment from './components/Comment'
const routes = [
{
path: '/customers',
component: Customer
},
{
path: '/posts',
component: Post
},
{
path: '/comments',
component: Comment
}
]
const router = createRouter({
routes,
history: createWebHistory()
})
createApp(App).use(router).mount('#app')

4
frontend/vue.config.js Normal file
View File

@ -0,0 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})

View File

@ -1,20 +1,20 @@
package np.something.DTO;
import np.something.model.Comment;
import np.something.model.Customer;
import np.something.model.Post;
public class CommentDto {
public final long id;
public final String content;
public final Customer customer;
public final Post post;
public final String customerName;
public final String postTitle;
public final String postAuthor;
public CommentDto(Comment comment) {
this.id = comment.getId();
this.content = comment.getContent();
this.customer = comment.getCustomer();
this.post = comment.getPost();
this.customerName = comment.getCustomer().getUsername();
this.postTitle = comment.getPost().getTitle();
this.postAuthor = comment.getPost().getCustomer().getUsername();
}
public long getId() {
@ -25,11 +25,13 @@ public class CommentDto {
return content;
}
public Customer getCustomer() {
return customer;
public String getCustomerName() {
return customerName;
}
public Post getPost() {
return post;
public String getPostTitle() {return postTitle;}
public String getPostAuthor() {
return postAuthor;
}
}

View File

@ -1,24 +1,22 @@
package np.something.DTO;
import np.something.model.Comment;
import np.something.model.Customer;
import np.something.model.Post;
import java.util.List;
public class CustomerDto {
public final long id;
public final String username;
public final String hashedPassword;
public final List<Comment> comments;
public final List<Post> posts;
public final String password;
public final List<CommentDto> comments;
public final List<PostDto> posts;
public CustomerDto(Customer customer) {
this.id = customer.getId();
this.username = customer.getUsername();
this.hashedPassword = customer.getPassword();
this.comments = customer.getComments();
this.posts = customer.getPosts();
this.password = customer.getPassword();
this.comments = customer.getComments().stream().map(CommentDto::new).toList();
this.posts = customer.getPosts().stream().map(PostDto::new).toList();
}
public long getId() {
@ -29,15 +27,15 @@ public class CustomerDto {
return username;
}
public String getHashedPassword() {
return hashedPassword;
public String getPassword() {
return password;
}
public List<Comment> getComments() {
public List<CommentDto> getComments() {
return comments;
}
public List<Post> getPosts() {
public List<PostDto> getPosts() {
return posts;
}
}

View File

@ -1,7 +1,5 @@
package np.something.DTO;
import np.something.model.Comment;
import np.something.model.Customer;
import np.something.model.Post;
import java.util.List;
@ -10,15 +8,15 @@ public class PostDto {
public final long id;
public final String title;
public final String content;
public final Customer customer;
public final List<Comment> comments;
public final String customerName;
public final List<CommentDto> comments;
public PostDto(Post post) {
this.id = post.getId();
this.title = post.getTitle();
this.content = post.getContent();
this.customer = post.getCustomer();
this.comments = post.getComments();
this.customerName = post.getCustomer().getUsername();
this.comments = post.getComments().stream().map(CommentDto::new).toList();
}
public long getId() {
@ -33,11 +31,11 @@ public class PostDto {
return content;
}
public Customer getCustomer() {
return customer;
public String getCustomerName() {
return customerName;
}
public List<Comment> getComments() {
public List<CommentDto> getComments() {
return comments;
}
}

View File

@ -0,0 +1,55 @@
package np.something.controllers;
import np.something.DTO.CommentDto;
import np.something.model.Comment;
import np.something.services.*;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/comment")
public class CommentController {
private final CommentService commentService;
private final CustomerService customerService;
private final PostService postService;
public CommentController(CommentService commentService, CustomerService customerService, PostService postService) {
this.commentService = commentService;
this.customerService = customerService;
this.postService = postService;
}
@GetMapping("/{id}")
public CommentDto getComment(@PathVariable Long id) {
return new CommentDto(commentService.findComment(id));
}
@GetMapping
public List<CommentDto> getComments() {
return commentService.findAllComments().stream()
.map(CommentDto::new)
.toList();
}
@PostMapping
public CommentDto createComment(@RequestParam("text") String text, @RequestParam("ownerId") Long ownerId, @RequestParam("postId") Long postId){
final Comment comment = commentService.addComment(customerService.findCustomer(ownerId), postService.findPost(postId), text);
return new CommentDto(comment);
}
@PutMapping("/{id}")
public CommentDto updateComment(@RequestParam("text") String text, @PathVariable Long id) {
return new CommentDto(commentService.updateComment(id, text));
}
@DeleteMapping("/{id}")
public CommentDto deleteComment(@PathVariable Long id) {
return new CommentDto(commentService.deleteComment(id));
}
@DeleteMapping
public void deleteAllComments(){
commentService.deleteAllComments();
}
}

View File

@ -0,0 +1,51 @@
package np.something.controllers;
import np.something.DTO.CustomerDto;
import np.something.model.Customer;
import np.something.services.*;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/customer")
public class CustomerController {
private final CustomerService customerService;
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@GetMapping("/{id}")
public CustomerDto getCustomer(@PathVariable Long id) {
return new CustomerDto(customerService.findCustomer(id));
}
@GetMapping
public List<CustomerDto> getCustomers() {
return customerService.findAllCustomers().stream()
.map(CustomerDto::new)
.toList();
}
@PostMapping
public CustomerDto createCustomer(@RequestParam("username") String username, @RequestParam("password") String password){
final Customer customer = customerService.addCustomer(username, password);
return new CustomerDto(customer);
}
@PutMapping("/{id}")
public CustomerDto updateCustomer(@RequestParam("username") String username, @RequestParam("password") String password, @PathVariable Long id) {
return new CustomerDto(customerService.updateCustomer(id, username, password));
}
@DeleteMapping("/{id}")
public CustomerDto deleteCustomer(@PathVariable Long id) {
return new CustomerDto(customerService.deleteCustomer(id));
}
@DeleteMapping
public void deleteAllCustomers(){
customerService.deleteAllCustomers();
}
}

View File

@ -0,0 +1,61 @@
package np.something.controllers;
import np.something.DTO.PostDto;
import np.something.services.CustomerService;
import np.something.services.PostService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/post")
public class PostController {
private final PostService postService;
private final CustomerService customerService;
public PostController(PostService postService, CustomerService customerService) {
this.postService = postService;
this.customerService = customerService;
}
@GetMapping("/{id}")
public PostDto getPost(@PathVariable Long id) {
return new PostDto(postService.findPost(id));
}
@GetMapping
public List<PostDto> getPosts() {
return postService.findAllPosts().stream()
.map(PostDto::new)
.toList();
}
@PostMapping
public PostDto createPost(
@RequestParam("title") String title,
@RequestParam("content") String content,
@RequestParam("authorId") Long authorId
)
{
return new PostDto(postService.addPost(customerService.findCustomer(authorId), title, content));
}
@PutMapping("/{id}")
public PostDto updatePost(
@PathVariable Long id,
@RequestParam("title") String title,
@RequestParam("content") String content
)
{
return new PostDto(postService.updatePost(id, title, content));
}
@DeleteMapping("/{id}")
public PostDto deletePost (@PathVariable Long id) {
return new PostDto(postService.deletePost(id));
}
@DeleteMapping
public void deleteAllPosts() {
postService.deleteAllPosts();
}
}

View File

@ -1,20 +1,24 @@
package np.something.util.error;
import np.something.Exceptions.CommentNotFoundException;
import np.something.Exceptions.CustomerNotFoundException;
import np.something.Exceptions.PostNotFoundException;
import np.something.util.validation.ValidationException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import ru.ulstu.is.sbapp.student.service.StudentNotFoundException;
import ru.ulstu.is.sbapp.util.validation.ValidationException;
import java.util.stream.Collectors;
@ControllerAdvice
public class AdviceController {
@ExceptionHandler({
StudentNotFoundException.class,
CommentNotFoundException.class,
CustomerNotFoundException.class,
PostNotFoundException.class,
ValidationException.class
})
public ResponseEntity<Object> handleException(Throwable e) {

View File

@ -2,10 +2,10 @@ package np.something.util.validation;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
import java.util.stream.Collectors;