Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
85f0c97e6f | |||
d75c758ee1 | |||
6d178b58aa | |||
9b72e39432 | |||
167ca7eb82 | |||
843ec51b8c | |||
9560588d41 | |||
b4e48f5c5e | |||
9f643c860d | |||
4d76a86c8e | |||
ce8c5ca468 | |||
15b5ebd034 | |||
81f8008aab | |||
307acf867a | |||
01470af3bb | |||
a0ff253478 | |||
973e2c6a16 | |||
8a23075ac6 | |||
43cc05427d | |||
e2d99cec86 | |||
8ecf9e9cab | |||
d0f9fb2bd0 | |||
2844d545ce | |||
c4e3593fa4 | |||
8fa5b5f8c4 | |||
663fd6ad72 | |||
b79d35d1af | |||
9297fb06ae | |||
438e1ed4d4 | |||
eea6638930 |
3
.idea/.gitignore
vendored
Normal file
3
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
10
.idea/compiler.xml
Normal file
10
.idea/compiler.xml
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<bytecodeTargetLevel>
|
||||
<module name="spring_online_calculator" target="17" />
|
||||
<module name="spring_online_calculator.main" target="17" />
|
||||
<module name="spring_online_calculator.test" target="17" />
|
||||
</bytecodeTargetLevel>
|
||||
</component>
|
||||
</project>
|
8
.idea/discord.xml
Normal file
8
.idea/discord.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="ASK" />
|
||||
<option name="nameOverrideEnabled" value="true" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
19
.idea/gradle.xml
Normal file
19
.idea/gradle.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||
<component name="GradleSettings">
|
||||
<option name="linkedExternalProjectsSettings">
|
||||
<GradleProjectSettings>
|
||||
<option name="delegatedBuild" value="true" />
|
||||
<option name="testRunner" value="GRADLE" />
|
||||
<option name="distributionType" value="DEFAULT_WRAPPED" />
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$/spring_online_calculator" />
|
||||
<option name="modules">
|
||||
<set>
|
||||
<option value="$PROJECT_DIR$/spring_online_calculator" />
|
||||
</set>
|
||||
</option>
|
||||
</GradleProjectSettings>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
15
.idea/inspectionProfiles/Project_Default.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="myValues">
|
||||
<value>
|
||||
<list size="1">
|
||||
<item index="0" class="java.lang.String" itemvalue="th:text" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
<option name="myCustomValuesEnabled" value="true" />
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
20
.idea/jarRepositories.xml
Normal file
20
.idea/jarRepositories.xml
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="MavenRepo" />
|
||||
<option name="name" value="MavenRepo" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
6
.idea/jpa-buddy.xml
Normal file
6
.idea/jpa-buddy.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JpaBuddyIdeaProjectConfig">
|
||||
<option name="defaultUnitInitialized" value="true" />
|
||||
</component>
|
||||
</project>
|
8
.idea/misc.xml
Normal file
8
.idea/misc.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="temurin-17" project-jdk-type="JavaSDK" />
|
||||
<component name="ProjectType">
|
||||
<option name="id" value="jpab" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/С репозитория.iml" filepath="$PROJECT_DIR$/.idea/С репозитория.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
124
.idea/uiDesigner.xml
Normal file
124
.idea/uiDesigner.xml
Normal file
@ -0,0 +1,124 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Palette2">
|
||||
<group name="Swing">
|
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||
</item>
|
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||
<initial-values>
|
||||
<property name="text" value="Button" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="RadioButton" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="CheckBox" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||
<initial-values>
|
||||
<property name="text" value="Label" />
|
||||
</initial-values>
|
||||
</item>
|
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||
<preferred-size width="150" height="-1" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||
<preferred-size width="150" height="50" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||
<preferred-size width="200" height="200" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||
</item>
|
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||
<preferred-size width="-1" height="20" />
|
||||
</default-constraints>
|
||||
</item>
|
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||
</item>
|
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||
</item>
|
||||
</group>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
9
.idea/С репозитория.iml
Normal file
9
.idea/С репозитория.iml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,16 @@
|
||||
{
|
||||
"name": "online_calculator",
|
||||
"name": "premuim_store",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"axios": "^1.3.5",
|
||||
"cors": "^2.8.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-router-dom": "^6.10.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
@ -3,9 +3,11 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>React App</title>
|
||||
<link href="../src/styles/App.css">
|
||||
<title>Premium store of our games! :)</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
2
front/premium_store/src/.env
Normal file
2
front/premium_store/src/.env
Normal file
@ -0,0 +1,2 @@
|
||||
VITE_NODE_ENV=development
|
||||
VITE_API_URL=http://localhost:8080
|
46
front/premium_store/src/App.js
Normal file
46
front/premium_store/src/App.js
Normal file
@ -0,0 +1,46 @@
|
||||
import React, {useState} from 'react';
|
||||
import { useRoutes, Outlet, BrowserRouter } from 'react-router-dom';
|
||||
import AddLevel from './components/AddLevel';
|
||||
import MainHead from './components/MainHead';
|
||||
import AddNation from './components/AddNation';
|
||||
import AddTank from './components/AddTank';
|
||||
import AddClient from './components/AddClient';
|
||||
import PageForChecking from './components/PageForChecking';
|
||||
|
||||
function Router(props) {
|
||||
return useRoutes(props.rootRoute);
|
||||
}
|
||||
|
||||
function App() {
|
||||
const routes = [
|
||||
{ index: true, element: <AddLevel /> },
|
||||
{ path: 'levels', element: <AddLevel />, label: 'Обзор уровней' },
|
||||
{ path: 'nations', element: <AddNation />, label: 'Обзор наций' },
|
||||
{ path: 'tanks', element: <AddTank />, label: 'Обзор танков'},
|
||||
{ path: 'clients', element: <AddClient />, label: 'Обзор клиентов'},
|
||||
{ path: 'checkPage', element: <PageForChecking />, label: 'Фильтр по танкам'}
|
||||
];
|
||||
|
||||
const links = routes.filter(route => route.hasOwnProperty('label'));
|
||||
|
||||
const rootRoute = [
|
||||
{ path: '/', element: render(links), children: routes }
|
||||
];
|
||||
|
||||
function render(links) {
|
||||
return (
|
||||
<div className="App">
|
||||
<MainHead links={links}/>
|
||||
<Outlet/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<Router rootRoute={ rootRoute } />
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
14
front/premium_store/src/components/AddClient.css
Normal file
14
front/premium_store/src/components/AddClient.css
Normal file
@ -0,0 +1,14 @@
|
||||
.add-client-input{
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 3px solid;
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
}
|
||||
|
||||
.add-level-button{
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
background-color: #FFE430;
|
||||
font-weight: 900;
|
||||
}
|
113
front/premium_store/src/components/AddClient.jsx
Normal file
113
front/premium_store/src/components/AddClient.jsx
Normal file
@ -0,0 +1,113 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import '../styles/App.css';
|
||||
import ClientList from './items/GameClient/ClientList';
|
||||
import './AddClient.css';
|
||||
|
||||
export default function AddClient() {
|
||||
const [clientItems, setClientItems] = useState([]);
|
||||
|
||||
//для создания нового уровня
|
||||
const [clientNickName, setClientNickName] = useState();
|
||||
|
||||
const [clientEmail, setClientEmail] = useState();
|
||||
|
||||
const [clientBalance, setClientBalance] = useState();
|
||||
|
||||
|
||||
//загрузка всех имеющихся уровней при старте
|
||||
useEffect(() => {
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/client/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setClientItems(responce.data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
//обновить список уровней
|
||||
function CheckArray(){
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/client/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setClientItems(responce.data)
|
||||
})
|
||||
}
|
||||
|
||||
//добавление нового уровня
|
||||
function addNewClient(){
|
||||
console.log(clientNickName);
|
||||
console.log(clientEmail);
|
||||
console.log(clientBalance);
|
||||
|
||||
if(clientNickName === ''){
|
||||
return;
|
||||
}
|
||||
else {//http://localhost:8080/client/?nickName=11&email=11&balance=11
|
||||
axios.post('http://localhost:8080/client/?nickName=' + clientNickName + '&email=' + clientEmail + '&balance=' + clientBalance)
|
||||
.then((response) => {
|
||||
CheckArray();
|
||||
setClientNickName('');
|
||||
setClientEmail('');
|
||||
setClientBalance('');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//добавили условную отрисовку
|
||||
return(
|
||||
<div>
|
||||
<div className="Group_create_level">
|
||||
<h1>Генератор клиентов</h1>
|
||||
<div>
|
||||
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||
Введите никнейм клиента:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientNickName}
|
||||
onChange={e => setClientNickName(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||
Введите почту клиента:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientEmail}
|
||||
onChange={e => setClientEmail(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{fontWeight: "900", marginTop:"10px"}}>
|
||||
Введите баланс клиента:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientBalance}
|
||||
onChange={e => setClientBalance(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button className='add-level-button'
|
||||
onClick={addNewClient}
|
||||
>
|
||||
Создать клиента
|
||||
</button>
|
||||
<button className='add-level-button'
|
||||
onClick={CheckArray}
|
||||
>
|
||||
Вывести всех клиентов
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Card_list">
|
||||
{clientItems.length !== 0
|
||||
?
|
||||
<ClientList clientItems={clientItems}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо клиенты!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
14
front/premium_store/src/components/AddLevel.css
Normal file
14
front/premium_store/src/components/AddLevel.css
Normal file
@ -0,0 +1,14 @@
|
||||
.add-level-input{
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 3px solid;
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
}
|
||||
|
||||
.add-level-button{
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
background-color: #FFE430;
|
||||
font-weight: 900;
|
||||
}
|
89
front/premium_store/src/components/AddLevel.jsx
Normal file
89
front/premium_store/src/components/AddLevel.jsx
Normal file
@ -0,0 +1,89 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import '../styles/App.css';
|
||||
import LevelList from './items/Level/LevelList';
|
||||
import './AddLevel.css';
|
||||
|
||||
//компонент для просмотра, создания и удаления уровней
|
||||
const AddLevel = () => {
|
||||
const [levelItems, setLevelItems] = useState([]);
|
||||
|
||||
//для создания нового уровня
|
||||
const [level, setLevel] = useState({level: ''});
|
||||
|
||||
//загрузка всех имеющихся уровней при старте
|
||||
useEffect(() => {
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/level/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setLevelItems(responce.data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
//обновить список уровней
|
||||
function CheckArray(){
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/level/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setLevelItems(responce.data)
|
||||
})
|
||||
}
|
||||
|
||||
//добавление нового уровня
|
||||
function addNewLevel(){
|
||||
if(level.level === ''){
|
||||
return;
|
||||
}
|
||||
else {
|
||||
axios.post('http://localhost:8080/level/?Level=' + parseInt(level.level, 10))
|
||||
.then((response) => {
|
||||
CheckArray();
|
||||
setLevel({level: ''});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//добавили условную отрисовку
|
||||
return(
|
||||
<div>
|
||||
<div className="Group_create_level">
|
||||
<h1>Генератор уровней</h1>
|
||||
<div>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Введите уровень:
|
||||
<input
|
||||
className="add-level-input"
|
||||
value={level.level}
|
||||
onChange={e => setLevel({level: e.target.value})}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button className='add-level-button'
|
||||
onClick={addNewLevel}
|
||||
>
|
||||
Создать уровень
|
||||
</button>
|
||||
<button className='add-level-button'
|
||||
onClick={CheckArray}
|
||||
>
|
||||
Вывести все уровни
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Card_list">
|
||||
{levelItems.length !== 0
|
||||
?
|
||||
<LevelList levelItems={levelItems}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо уровни!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddLevel;
|
14
front/premium_store/src/components/AddNation.css
Normal file
14
front/premium_store/src/components/AddNation.css
Normal file
@ -0,0 +1,14 @@
|
||||
.add-nation-input{
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 3px solid;
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
}
|
||||
|
||||
.add-level-button{
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
background-color: #FFE430;
|
||||
font-weight: 900;
|
||||
}
|
89
front/premium_store/src/components/AddNation.jsx
Normal file
89
front/premium_store/src/components/AddNation.jsx
Normal file
@ -0,0 +1,89 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import '../styles/App.css';
|
||||
import NationList from './items/Nation/NationList';
|
||||
import './AddNation.css';
|
||||
|
||||
//компонент для просмотра, создания и удаления уровней
|
||||
const AddNation = () => {
|
||||
const [nationItems, setNationItems] = useState([]);
|
||||
|
||||
//для создания нового уровня
|
||||
const [nation, setNation] = useState({nation: ''});
|
||||
|
||||
//загрузка всех имеющихся уровней при старте
|
||||
useEffect(() => {
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/nation/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setNationItems(responce.data)
|
||||
})
|
||||
}, [])
|
||||
|
||||
//обновить список уровней
|
||||
function CheckArray(){
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/nation/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setNationItems(responce.data)
|
||||
})
|
||||
}
|
||||
|
||||
//добавление нового уровня
|
||||
function addNewNation(){
|
||||
if(nation.nation === ''){
|
||||
return;
|
||||
}
|
||||
else {
|
||||
axios.post('http://localhost:8080/nation/?nation=' + nation.nation)
|
||||
.then((response) => {
|
||||
CheckArray();
|
||||
setNation({nation: ''});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//добавили условную отрисовку
|
||||
return(
|
||||
<div>
|
||||
<div className="Group_create_level">
|
||||
<h1>Генератор наций</h1>
|
||||
<div>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Введите нацию:
|
||||
<input
|
||||
className="add-nation-input"
|
||||
value={nation.nation}
|
||||
onChange={e => setNation({nation: e.target.value})}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button className='add-level-button'
|
||||
onClick={addNewNation}
|
||||
>
|
||||
Создать нацию
|
||||
</button>
|
||||
<button className='add-level-button'
|
||||
onClick={CheckArray}
|
||||
>
|
||||
Вывести все нации
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Card_list">
|
||||
{nationItems.length !== 0
|
||||
?
|
||||
<NationList nationItems={nationItems}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо нации!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AddNation;
|
15
front/premium_store/src/components/AddTank.css
Normal file
15
front/premium_store/src/components/AddTank.css
Normal file
@ -0,0 +1,15 @@
|
||||
.add-tank-input{
|
||||
margin-top: 10px;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
border: 3px solid;
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
}
|
||||
|
||||
.add-level-button{
|
||||
border-radius: 10px;
|
||||
border-color: #505050;
|
||||
background-color: #FFE430;
|
||||
font-weight: 900;
|
||||
}
|
198
front/premium_store/src/components/AddTank.jsx
Normal file
198
front/premium_store/src/components/AddTank.jsx
Normal file
@ -0,0 +1,198 @@
|
||||
import React, { useState, useEffect, useRef} from 'react';
|
||||
import axios from 'axios';
|
||||
import '../styles/App.css';
|
||||
import TankList from './items/Tank/TankList';
|
||||
import './AddTank.css';
|
||||
|
||||
const AddTank = () => {
|
||||
const [tankItems, setTankItems] = useState([]);
|
||||
|
||||
//для создания нового танка
|
||||
const [tankName, setTankName] = useState({tankName: ''});
|
||||
|
||||
const [tankCost, setTankCost] = useState({tankCost: ''});
|
||||
|
||||
const [nationItems, setNationItems] = useState([]);
|
||||
|
||||
const [levelItems, setLevelItems] = useState([]);
|
||||
|
||||
//храним выбранные нацию и уровень для нового танка
|
||||
const [chooiceNation, setChooiceNation] = useState();
|
||||
const [chooiceLevel, setChooiceLevel] = useState();
|
||||
|
||||
const [fileByte, setFileByte] = useState(null);
|
||||
const inputRef = useRef();
|
||||
|
||||
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||
useEffect(() => {
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/tank/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setTankItems(responce.data)
|
||||
});
|
||||
axios.get('http://localhost:8080/level/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setLevelItems(responce.data)
|
||||
});
|
||||
axios.get('http://localhost:8080/nation/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setNationItems(responce.data)
|
||||
});
|
||||
}, [])
|
||||
|
||||
//обновить список танков
|
||||
function CheckArray(){
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/tank/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setTankItems(responce.data)
|
||||
})
|
||||
}
|
||||
|
||||
//добавление нового танка
|
||||
async function addNewTank(){
|
||||
console.log(tankName);
|
||||
console.log(tankCost);
|
||||
console.log(chooiceNation);
|
||||
console.log(chooiceLevel);
|
||||
//console.log(imageURL);
|
||||
|
||||
//const header = new Headers({ "Access-Control-Allow-Origin": "*" });
|
||||
|
||||
axios.post("http://localhost:8080/tank/?firstName=" + tankName.tankName +
|
||||
"&id=" + chooiceNation.id + "&nationId=" + chooiceNation + "&levelId=" + chooiceLevel +
|
||||
"&cost=" + tankCost.tankCost)
|
||||
.then((response) => {
|
||||
console.log("Успешное добавление");
|
||||
console.log(response.data);
|
||||
CheckArray();
|
||||
setTankCost({tankCost: ''});
|
||||
setTankName({tankName: ''});
|
||||
});
|
||||
|
||||
//}*/
|
||||
}
|
||||
|
||||
//хранит картинку для танка
|
||||
const [imageURL, setImageURL] = useState();
|
||||
|
||||
const fileReader = new FileReader();
|
||||
fileReader.onloadend = () => {
|
||||
const tempval = fileReader.result
|
||||
setImageURL(tempval);
|
||||
};
|
||||
|
||||
function handleOnChange(event) {
|
||||
event.preventDefault();
|
||||
const file = event.target.files[0];
|
||||
fileReader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
const getChoiceNation = (newId) => {
|
||||
setChooiceNation(nationItems[newId - 1].id);
|
||||
}
|
||||
|
||||
const getChoiceLevel = (newId) => {
|
||||
setChooiceLevel(levelItems[newId - 1].id);
|
||||
}
|
||||
|
||||
//для добавления картинок
|
||||
/*<p style={{fontWeight: "900", marginTop: "10px"}}>
|
||||
Выберите изображение:
|
||||
<input className="add-tank-input" id="formFileSm" type="file"
|
||||
accept="image/jpeg, image/png, image/jpg"
|
||||
value=''
|
||||
style={{marginTop: "10px"}}
|
||||
//onChange={e => setTank({tankImage: e.target.value})}
|
||||
//onChange={() => setTank({tankImage: inputRef.current.files[0]})}
|
||||
onChange={handleOnChange}
|
||||
//ref={inputRef}
|
||||
/>
|
||||
</p>*/
|
||||
|
||||
//добавили условную отрисовку
|
||||
return(
|
||||
<div>
|
||||
<div className="Group_create_level">
|
||||
<h1>Генератор танков</h1>
|
||||
<div>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите нацию:
|
||||
<select
|
||||
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите нацию</option>
|
||||
{nationItems.map((nationItem) =>
|
||||
<option
|
||||
value={nationItem.nation}
|
||||
key={nationItem.id}
|
||||
>
|
||||
{nationItem.nation}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите уровень:
|
||||
<select style={{marginTop: "10px"}}
|
||||
onChange={(event) => getChoiceLevel(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите уровень</option>
|
||||
{levelItems.map((levelItem) =>
|
||||
<option
|
||||
value={levelItem.level}
|
||||
key={levelItem.id}
|
||||
>
|
||||
{levelItem.level}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Введите название:
|
||||
<input
|
||||
className="add-tank-input"
|
||||
value={tankName.tankName}
|
||||
onChange={e => setTankName({tankName: e.target.value})}
|
||||
/>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Введите стоимость:
|
||||
<input
|
||||
className="add-tank-input"
|
||||
value={tankCost.tankCost}
|
||||
onChange={e => setTankCost({tankCost: e.target.value})}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<button className='add-level-button'
|
||||
onClick={addNewTank}
|
||||
>
|
||||
Создать танк
|
||||
</button>
|
||||
<button className='add-level-button'
|
||||
onClick={CheckArray}
|
||||
>
|
||||
Вывести все танки
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="Card_list">
|
||||
{tankItems.length !== 0
|
||||
?
|
||||
<TankList tankItems={tankItems}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо танки!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default AddTank
|
41
front/premium_store/src/components/MainHead.jsx
Normal file
41
front/premium_store/src/components/MainHead.jsx
Normal file
@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import '../styles/App.css';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
//компонент с кнопками навигации по сайту
|
||||
const MainHead = (props) => {
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div>
|
||||
<h1 className="Main-label">Мир танков</h1>
|
||||
</div>
|
||||
<form className="collapse navbar-collapse">
|
||||
<nav className="navbar navbar-expand-lg justify-content-around">
|
||||
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" style={{backgroundColor: '#379dc2'}}>
|
||||
<span className="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div className="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul className="Main_head navbar-nav me-auto align-items-center">
|
||||
{
|
||||
props.links.map(route =>
|
||||
<li key={route.path}
|
||||
className="nav-item">
|
||||
<div className="Button_Main_Group container p-2" div="div">
|
||||
<NavLink className="nav-link btn border border-3 border-dark fs-4 lh-15" role="button"
|
||||
to={route.path}>
|
||||
{route.label}
|
||||
</NavLink>
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MainHead;
|
133
front/premium_store/src/components/PageForChecking.jsx
Normal file
133
front/premium_store/src/components/PageForChecking.jsx
Normal file
@ -0,0 +1,133 @@
|
||||
import React, { useState, useEffect, useRef} from 'react';
|
||||
import axios from 'axios';
|
||||
import '../styles/App.css';
|
||||
import TankList from './items/Tank/TankList';
|
||||
import './AddTank.css';
|
||||
|
||||
const PageForChecking = () => {
|
||||
|
||||
const[tankItems, setTankItems] = useState([]);
|
||||
|
||||
const [nationItems, setNationItems] = useState([]);
|
||||
|
||||
const [levelItems, setLevelItems] = useState([]);
|
||||
|
||||
const [chooiceNation, setChooiceNation] = useState();
|
||||
|
||||
const [chooiceFirstLevel, setChooiceFirstLevel] = useState();
|
||||
|
||||
const [chooiceSecondLevel, setChooiceSecondLevel] = useState();
|
||||
|
||||
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||
useEffect(() => {
|
||||
axios.get('http://localhost:8080/level/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setLevelItems(responce.data)
|
||||
});
|
||||
axios.get('http://localhost:8080/nation/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setNationItems(responce.data)
|
||||
});
|
||||
}, [])
|
||||
|
||||
const getChoiceNation = (newId) => {
|
||||
setChooiceNation(nationItems[newId - 1].nation);
|
||||
}
|
||||
|
||||
const getChooiceFirstLevel = (newId) => {
|
||||
setChooiceFirstLevel(levelItems[newId - 1].level);
|
||||
}
|
||||
|
||||
const getChooiceSecondLevel = (newId) => {
|
||||
setChooiceSecondLevel(levelItems[newId - 1].level);
|
||||
}
|
||||
|
||||
function findList(){
|
||||
console.log(chooiceNation);
|
||||
console.log(chooiceFirstLevel);
|
||||
console.log(chooiceSecondLevel);
|
||||
|
||||
axios.get('http://localhost:8080/tank/filteredList/?nation=' + chooiceNation + '&firstLevel=' + chooiceFirstLevel + '&secondLevel=' + chooiceSecondLevel)
|
||||
.then((response) => {
|
||||
setTankItems(response.data)
|
||||
});
|
||||
|
||||
console.log(tankItems)
|
||||
}
|
||||
|
||||
return(
|
||||
<div>
|
||||
<div className="Group_create_level">
|
||||
<h1>Фильтрация танков</h1>
|
||||
<div>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите нацию:
|
||||
<select
|
||||
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите нацию</option>
|
||||
{nationItems.map((nationItem) =>
|
||||
<option
|
||||
value={nationItem.nation}
|
||||
key={nationItem.id}
|
||||
>
|
||||
{nationItem.nation}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите начальный диапазон уровней:
|
||||
<select style={{marginTop: "10px"}}
|
||||
onChange={(event) => getChooiceFirstLevel(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите уровень</option>
|
||||
{levelItems.map((levelItem) =>
|
||||
<option
|
||||
value={levelItem.level}
|
||||
key={levelItem.id}
|
||||
>
|
||||
{levelItem.level}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите конечный диапазон уровней:
|
||||
<select style={{marginTop: "10px"}}
|
||||
onChange={(event) => getChooiceSecondLevel(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите уровень</option>
|
||||
{levelItems.map((levelItem) =>
|
||||
<option
|
||||
value={levelItem.level}
|
||||
key={levelItem.id}
|
||||
>
|
||||
{levelItem.level}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
</div>
|
||||
<button className='add-level-button'
|
||||
onClick={findList}
|
||||
>
|
||||
Найти танки
|
||||
</button>
|
||||
</div>
|
||||
<div className="Card_list">
|
||||
{tankItems.length !== 0
|
||||
?
|
||||
<TankList tankItems={tankItems}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>Отсутствуют какие-либо танки при таком фильтре!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default PageForChecking
|
@ -0,0 +1,37 @@
|
||||
.client-card{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin-top: 5px;
|
||||
border: 5px solid;
|
||||
border-color: #14A76C;
|
||||
border-radius: 10px;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.client-attribute{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.client-button-group{
|
||||
display: flex;
|
||||
width: 20%;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.client-button{
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import './ClientItem.css';
|
||||
import ModalClient from './ModalClient';
|
||||
import ModalTankNation from '../Nation/ModalTankNation';
|
||||
|
||||
const ClientItem = (data) => {
|
||||
|
||||
const [client, setClient] = useState(null);
|
||||
|
||||
//состояние для контроля вызова модального окна
|
||||
const[modal, setModal] = useState(false);
|
||||
|
||||
//состояние для вызова окна показа списка танков нации
|
||||
const[modalNation, setModalNation] = useState(false);
|
||||
|
||||
function deleteClient(){
|
||||
axios.delete('http://localhost:8080/client/' + data.clientItem.id)
|
||||
.then((response) => {
|
||||
console.log("Удаление уровня с id " + data.clientItem.id)
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="client-card">
|
||||
<p className="client-attribute"> id: {data.clientItem.id} </p>
|
||||
<p className="client-attribute"> Никнейм: {data.clientItem.nickName} </p>
|
||||
<p className="client-attribute"> Баланс: {data.clientItem.balance} </p>
|
||||
<p className="client-attribute"> Почта: {data.clientItem.email} </p>
|
||||
<div className='client-button-group'>
|
||||
<button className="client-button" type="button"
|
||||
onClick={() => setModal(true)}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
<button className="client-button" type="button"
|
||||
onClick={deleteClient}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
<button className="nation-button" type="button"
|
||||
onClick={() => setModalNation(true)}
|
||||
>
|
||||
Список танков
|
||||
</button>
|
||||
<ModalClient
|
||||
data={data.clientItem}
|
||||
visible={modal}
|
||||
setVisible={setModal}
|
||||
/>
|
||||
<ModalTankNation
|
||||
data={data.clientItem}
|
||||
visible={modalNation}
|
||||
setVisible={setModalNation}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ClientItem
|
@ -0,0 +1,22 @@
|
||||
import React, { useEffect} from 'react';
|
||||
import ClientItem from './ClientItem';
|
||||
|
||||
const ClientList = (clients) => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||
Список существующих клиентов:
|
||||
</h1>
|
||||
</div>
|
||||
{clients.clientItems.map((clientItem) =>
|
||||
<ClientItem
|
||||
clientItem={clientItem}
|
||||
key={clientItem.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ClientList;
|
@ -0,0 +1,106 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import cl from '../GameClient/ModalClient.module.css';
|
||||
import '../../AddClient.css';
|
||||
|
||||
const ModalClient = ({data, visible, setVisible}) => {
|
||||
|
||||
//для обновления уровня
|
||||
const [clientNickName, setClientNickName] = useState(data.nickName);
|
||||
|
||||
const [clientEmail, setClientEmail] = useState(data.email);
|
||||
|
||||
const [clientBalance, setClientBalance] = useState(data.balance);
|
||||
|
||||
const [clientTank, setClientTank] = useState(null);
|
||||
|
||||
const [tankItems, setTankItems] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
console.log('Обращение к БД');
|
||||
axios.get('http://localhost:8080/tank/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setTankItems(responce.data)
|
||||
});
|
||||
}, [])
|
||||
|
||||
//для контроля видимости модалки
|
||||
const rootClasses = [cl.myModal];
|
||||
|
||||
if(visible)
|
||||
{
|
||||
rootClasses.push(cl.active);
|
||||
}
|
||||
|
||||
//добавление нового уровня
|
||||
function updateLevel(){
|
||||
axios.put('http://localhost:8080/client/' + data.id + '?nickName='
|
||||
+ clientNickName + '&email=' + clientEmail + '&balance=' + clientBalance + '&tankId=' + clientTank)
|
||||
.then((response) => {
|
||||
console.log("Обновление клиента с id " + data.id)
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
const getChoiceNation = (newId) => {
|
||||
setClientTank(tankItems[newId - 1].id);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||
<p style={{marginTop: "10px"}}>
|
||||
Никнейм:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientNickName}
|
||||
onChange={e => setClientNickName(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{marginTop: "10px"}}>
|
||||
Почта:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientEmail}
|
||||
onChange={e => setClientEmail(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{marginTop: "10px"}}>
|
||||
Баланс:
|
||||
<input
|
||||
className="add-client-input"
|
||||
value={clientBalance}
|
||||
onChange={e => setClientBalance(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите новый танк:
|
||||
<select
|
||||
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите танк</option>
|
||||
{tankItems.map((tankItem) =>
|
||||
<option
|
||||
value={tankItem.name}
|
||||
key={tankItem.id}
|
||||
>
|
||||
{tankItem.name}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<button
|
||||
style={{marginTop: "10px"}}
|
||||
className={cl.modalButton}
|
||||
type="button"
|
||||
onClick={updateLevel}
|
||||
>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalClient
|
@ -0,0 +1,34 @@
|
||||
.myModal{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.myModal.active{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.myModalContent{
|
||||
display: inline-block;
|
||||
padding: 15px;
|
||||
background: #FF652F;
|
||||
border-radius: 16px;
|
||||
min-width: 300px;
|
||||
min-height: 100px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modalButton{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FFE430;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
37
front/premium_store/src/components/items/Level/LevelItem.css
Normal file
37
front/premium_store/src/components/items/Level/LevelItem.css
Normal file
@ -0,0 +1,37 @@
|
||||
.level-card{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin-top: 5px;
|
||||
border: 5px solid;
|
||||
border-color: #14A76C;
|
||||
border-radius: 10px;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.level-attribute{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.level-button-group{
|
||||
display: flex;
|
||||
width: 20%;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.level-button{
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
46
front/premium_store/src/components/items/Level/LevelItem.jsx
Normal file
46
front/premium_store/src/components/items/Level/LevelItem.jsx
Normal file
@ -0,0 +1,46 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import './LevelItem.css';
|
||||
import ModalLevel from './ModalLevel';
|
||||
|
||||
//отвечает за отдельно взятый уровень (вывод карточки с ним)
|
||||
const LevelItem = (data) => {
|
||||
|
||||
const [level, setLevel] = useState(null);
|
||||
|
||||
//состояние для контроля вызова модального окна
|
||||
const[modal, setModal] = useState(false);
|
||||
|
||||
function deleteLevel(){
|
||||
axios.delete('http://localhost:8080/level/' + data.levelItem.id)
|
||||
.then((response) => {
|
||||
console.log("Удаление уровня с id " + data.levelItem.id)
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="level-card">
|
||||
<p className="level-attribute"> id: {data.levelItem.id} </p>
|
||||
<p className="level-attribute"> уровень: {data.levelItem.level} </p>
|
||||
<div className='level-button-group'>
|
||||
<button className="level-button" type="button"
|
||||
onClick={() => setModal(true)}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
<button className="level-button" type="button"
|
||||
onClick={deleteLevel}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
<ModalLevel
|
||||
data={data.levelItem}
|
||||
visible={modal}
|
||||
setVisible={setModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LevelItem;
|
25
front/premium_store/src/components/items/Level/LevelList.jsx
Normal file
25
front/premium_store/src/components/items/Level/LevelList.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { useEffect} from 'react';
|
||||
import LevelItem from './LevelItem';
|
||||
|
||||
//const host = import.meta.env.VITE_API_URL;
|
||||
|
||||
//отвечает за список всех уровней. Передаём сюда пропсом массив уровней
|
||||
const LevelList = (levels) => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||
Список существующих уровней:
|
||||
</h1>
|
||||
</div>
|
||||
{levels.levelItems.map((levelItem) =>
|
||||
<LevelItem
|
||||
levelItem={levelItem}
|
||||
key={levelItem.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LevelList;
|
@ -0,0 +1,49 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import cl from './ModalLevel.module.css';
|
||||
import '../../AddLevel.css';
|
||||
|
||||
const ModalLevel = ({data, visible, setVisible}) => {
|
||||
|
||||
//для обновления уровня
|
||||
const [level, setLevel] = useState(data.level);
|
||||
|
||||
//для контроля видимости модалки
|
||||
const rootClasses = [cl.myModal];
|
||||
|
||||
if(visible)
|
||||
{
|
||||
rootClasses.push(cl.active);
|
||||
}
|
||||
|
||||
//добавление нового уровня
|
||||
function updateLevel(){
|
||||
setLevel()
|
||||
axios.put('http://localhost:8080/level/' + data.id + '?Level=' + level)
|
||||
.then((response) => {
|
||||
console.log("Обновление уровня с id " + data.id)
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||
<input
|
||||
className="add-level-input"
|
||||
value={level}
|
||||
onChange={e => setLevel(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className={cl.modalButton}
|
||||
type="button"
|
||||
onClick={updateLevel}
|
||||
>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModalLevel;
|
@ -0,0 +1,34 @@
|
||||
.myModal{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.myModal.active{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.myModalContent{
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
background: #FF652F;
|
||||
border-radius: 16px;
|
||||
min-width: 300px;
|
||||
min-height: 100px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modalButton{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FFE430;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import cl from './ModalNation.module.css';
|
||||
import '../../AddNation.css';
|
||||
|
||||
const ModalNation = ({data, visible, setVisible}) => {
|
||||
//для обновления уровня
|
||||
const [nation, setNation] = useState(data.nation);
|
||||
|
||||
const nullId = 0;
|
||||
|
||||
//для контроля видимости модалки
|
||||
const rootClasses = [cl.myModal];
|
||||
|
||||
if(visible)
|
||||
{
|
||||
rootClasses.push(cl.active);
|
||||
}
|
||||
|
||||
//добавление новой нации
|
||||
function updateLevel(){
|
||||
setNation()
|
||||
axios.put('http://localhost:8080/nation/' + data.id + '?nation=' + nation + '&tankId=' + nullId)
|
||||
.then((response) => {
|
||||
console.log("Обновление нации с id " + data.id)
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||
<input
|
||||
className="add-nation-input"
|
||||
value={nation}
|
||||
onChange={e => setNation(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className={cl.modalButton}
|
||||
type="button"
|
||||
onClick={updateLevel}
|
||||
>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalNation
|
@ -0,0 +1,34 @@
|
||||
.myModal{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.myModal.active{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.myModalContent{
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
background: #FF652F;
|
||||
border-radius: 16px;
|
||||
min-width: 300px;
|
||||
min-height: 100px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modalButton{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FFE430;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import cl from './ModalNation.module.css';
|
||||
import '../../AddNation.css';
|
||||
import TankList from '../Tank/TankList';
|
||||
import { useFetcher } from 'react-router-dom';
|
||||
|
||||
const ModalTankNation = ({data, visible, setVisible}) => {
|
||||
//для обновления уровня
|
||||
const [nation, setNation] = useState(data.tanks);
|
||||
|
||||
//для контроля видимости модалки
|
||||
const rootClasses = [cl.myModal];
|
||||
|
||||
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||
useEffect(() => {
|
||||
console.log("Загрузка МОДАЛКИ №1")
|
||||
console.log(nation);
|
||||
}, [])
|
||||
|
||||
if(visible)
|
||||
{
|
||||
rootClasses.push(cl.active);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||
{nation.length !== 0
|
||||
?
|
||||
<TankList
|
||||
label={"Список танков у нации"}
|
||||
tankItems={nation}
|
||||
/>
|
||||
:
|
||||
<h1 style={{textAlign: 'center'}}>В БД отсутствуют какие-либо танки данной нации!</h1>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalTankNation
|
@ -0,0 +1,38 @@
|
||||
.nation-card{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin-top: 5px;
|
||||
border: 5px solid;
|
||||
border-color: #14A76C;
|
||||
border-radius: 10px;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.nation-attribute{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nation-button-group{
|
||||
display: flex;
|
||||
margin: 10px;
|
||||
width: 20%;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.nation-button{
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import './NationItem.css';
|
||||
import ModalNation from './ModalNation';
|
||||
import ModalTankNation from './ModalTankNation';
|
||||
|
||||
//отвечает за отдельно взятую нацию (вывод карточки с ним)
|
||||
const NationItem = (data) => {
|
||||
const [nation, setNation] = useState(null);
|
||||
|
||||
//состояние для контроля вызова модального окна
|
||||
const[modal, setModal] = useState(false);
|
||||
|
||||
//состояние для вызова окна показа списка танков нации
|
||||
const[modalNation, setModalNation] = useState(false);
|
||||
|
||||
function deleteNation(){
|
||||
axios.delete('http://localhost:8080/nation/' + data.nationItem.id)
|
||||
.then((response) => {
|
||||
console.log("Удаление нации с id " + data.nationItem.id)
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="nation-card">
|
||||
<p className="nation-attribute"> id: {data.nationItem.id} </p>
|
||||
<p className="nation-attribute"> нация: {data.nationItem.nation} </p>
|
||||
<div className='nation-button-group'>
|
||||
<button className="nation-button" type="button"
|
||||
onClick={() => setModal(true)}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
<button className="nation-button" type="button"
|
||||
onClick={deleteNation}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
<button className="nation-button" type="button"
|
||||
onClick={() => setModalNation(true)}
|
||||
>
|
||||
Список танков
|
||||
</button>
|
||||
<ModalNation
|
||||
data={data.nationItem}
|
||||
visible={modal}
|
||||
setVisible={setModal}
|
||||
/>
|
||||
<ModalTankNation
|
||||
data={data.nationItem}
|
||||
visible={modalNation}
|
||||
setVisible={setModalNation}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default NationItem
|
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
import NationItem from './NationItem';
|
||||
|
||||
const NationList = (nations) => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||
Список существующих наций:
|
||||
</h1>
|
||||
</div>
|
||||
{nations.nationItems.map((nationItem) =>
|
||||
<NationItem
|
||||
nationItem={nationItem}
|
||||
key={nationItem.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default NationList
|
125
front/premium_store/src/components/items/Tank/ModalTank.jsx
Normal file
125
front/premium_store/src/components/items/Tank/ModalTank.jsx
Normal file
@ -0,0 +1,125 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import cl from './ModalTank.module.css';
|
||||
import '../../AddTank.css';
|
||||
|
||||
const ModalTank = ({data, visible, setVisible}) => {
|
||||
//для обновления танка
|
||||
const [tankName, setTankName] = useState(data.name);
|
||||
|
||||
const [tankCost, setTankCost] = useState(data.cost);
|
||||
|
||||
const [chooiceNation, setChoiceNation] = useState(data.nation.id);
|
||||
|
||||
const [chooiceLevel, setChoiceLevel] = useState(data.nation.id);
|
||||
|
||||
const [nationItems, setNationItems] = useState([]);
|
||||
|
||||
const [levelItems, setLevelItems] = useState([]);
|
||||
|
||||
//загрузка всех имеющихся танков, а также уровней и наций при старте
|
||||
useEffect(() => {
|
||||
axios.get('http://localhost:8080/level/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setLevelItems(responce.data)
|
||||
});
|
||||
axios.get('http://localhost:8080/nation/')
|
||||
.then((responce) => {
|
||||
console.log(responce.data);
|
||||
setNationItems(responce.data)
|
||||
});
|
||||
}, [])
|
||||
|
||||
//для контроля видимости модалки
|
||||
const rootClasses = [cl.myModal];
|
||||
|
||||
if(visible)
|
||||
{
|
||||
rootClasses.push(cl.active);
|
||||
}
|
||||
|
||||
//добавление нового танка
|
||||
function updateLevel(){
|
||||
setTankName()
|
||||
axios.put('http://localhost:8080/tank/' + data.id + '?firstName=' + tankName + '&nationId='
|
||||
+ chooiceNation + '&levelId=' + chooiceLevel + '&cost=' + tankCost)
|
||||
.then((response) => {
|
||||
console.log("Обновление танка с id " + data.id)
|
||||
});
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
const getChoiceNation = (newId) => {
|
||||
setChoiceNation(nationItems[newId - 1].id);
|
||||
}
|
||||
|
||||
const getChoiceLevel = (newId) => {
|
||||
setChoiceLevel(levelItems[newId - 1].id);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div className={rootClasses.join(' ')} onClick={() => setVisible(false)}>
|
||||
<div className={cl.myModalContent} onClick={(e) => e.stopPropagation()}>
|
||||
<p>
|
||||
Название:
|
||||
<input
|
||||
className="add-tank-input"
|
||||
value={tankName}
|
||||
onChange={e => setTankName(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
Стоимость:
|
||||
<input
|
||||
className="add-tank-input"
|
||||
value={tankCost}
|
||||
onChange={e => setTankCost(e.target.value)}
|
||||
/>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите нацию:
|
||||
<select
|
||||
onChange={(event) => getChoiceNation(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите нацию</option>
|
||||
{nationItems.map((nationItem) =>
|
||||
<option
|
||||
value={nationItem.nation}
|
||||
key={nationItem.id}
|
||||
>
|
||||
{nationItem.nation}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<p style={{fontWeight: "900"}}>
|
||||
Выберите уровень:
|
||||
<select style={{marginTop: "10px"}}
|
||||
onChange={(event) => getChoiceLevel(event.target.selectedIndex)}
|
||||
>
|
||||
<option selected>Выберите уровень</option>
|
||||
{levelItems.map((levelItem) =>
|
||||
<option
|
||||
value={levelItem.level}
|
||||
key={levelItem.id}
|
||||
>
|
||||
{levelItem.level}
|
||||
</option>
|
||||
)}
|
||||
</select>
|
||||
</p>
|
||||
<button
|
||||
className={cl.modalButton}
|
||||
type="button"
|
||||
onClick={updateLevel}
|
||||
>
|
||||
Сохранить
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ModalTank
|
@ -0,0 +1,33 @@
|
||||
.myModal{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: none;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.myModal.active{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.myModalContent{
|
||||
display: inline-block;
|
||||
padding: 15px;
|
||||
background: #FF652F;
|
||||
border-radius: 16px;
|
||||
min-width: 300px;
|
||||
min-height: 100px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modalButton{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FFE430;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
37
front/premium_store/src/components/items/Tank/TankItem.css
Normal file
37
front/premium_store/src/components/items/Tank/TankItem.css
Normal file
@ -0,0 +1,37 @@
|
||||
.tank-card{
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 15px;
|
||||
margin-top: 5px;
|
||||
border: 5px solid;
|
||||
border-color: #14A76C;
|
||||
border-radius: 10px;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.tank-attribute{
|
||||
padding: 5px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tank-button-group{
|
||||
display: flex;
|
||||
width: 20%;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tank-button{
|
||||
padding: 10px;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
48
front/premium_store/src/components/items/Tank/TankItem.jsx
Normal file
48
front/premium_store/src/components/items/Tank/TankItem.jsx
Normal file
@ -0,0 +1,48 @@
|
||||
import React, { useState } from 'react';
|
||||
import axios from 'axios';
|
||||
import './TankItem.css';
|
||||
import ModalTank from './ModalTank';
|
||||
|
||||
const TankItem = (data) => {
|
||||
|
||||
const [tank, setTank] = useState(null);
|
||||
|
||||
//состояние для контроля вызова модального окна
|
||||
const[modal, setModal] = useState(false);
|
||||
|
||||
function deleteTank(){
|
||||
axios.delete('http://localhost:8080/tank/' + data.tankItem.id)
|
||||
.then((response) => {
|
||||
console.log("Удаление танка с id " + data.tankItem.id)
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tank-card">
|
||||
<p className="tank-attribute"> id: {data.tankItem.id} </p>
|
||||
<p className="tank-attribute"> название: {data.tankItem.name} </p>
|
||||
<p className="tank-attribute"> уровень: {data.tankItem.level.level} </p>
|
||||
<p className="tank-attribute"> нация: {data.tankItem.nation.nation} </p>
|
||||
<p className="tank-attribute"> стоимость: {data.tankItem.cost} </p>
|
||||
<div className='tank-button-group'>
|
||||
<button className="tank-button" type="button"
|
||||
onClick={() => setModal(true)}
|
||||
>
|
||||
Редактировать
|
||||
</button>
|
||||
<button className="tank-button" type="button"
|
||||
onClick={deleteTank}
|
||||
>
|
||||
Удалить
|
||||
</button>
|
||||
<ModalTank
|
||||
data={data.tankItem}
|
||||
visible={modal}
|
||||
setVisible={setModal}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TankItem
|
22
front/premium_store/src/components/items/Tank/TankList.jsx
Normal file
22
front/premium_store/src/components/items/Tank/TankList.jsx
Normal file
@ -0,0 +1,22 @@
|
||||
import React from 'react'
|
||||
import TankItem from './TankItem';
|
||||
|
||||
const TankList = (tanks) => {
|
||||
return (
|
||||
<div>
|
||||
<div>
|
||||
<h1 style={{textAlign: 'center', fontFamily: 'courier, monospace', background: '#FF652F', borderRadius: '10px'}}>
|
||||
Список существующих наций:
|
||||
</h1>
|
||||
</div>
|
||||
{tanks.tankItems.map((tankItem) =>
|
||||
<TankItem
|
||||
tankItem={tankItem}
|
||||
key={tankItem.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default TankList;
|
BIN
front/premium_store/src/images/wot-268-4.jpg
Normal file
BIN
front/premium_store/src/images/wot-268-4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 497 KiB |
BIN
front/premium_store/src/images/wot-is-4.jpg
Normal file
BIN
front/premium_store/src/images/wot-is-4.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 474 KiB |
8
front/premium_store/src/index.js
Normal file
8
front/premium_store/src/index.js
Normal file
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<App />
|
||||
);
|
90
front/premium_store/src/styles/App.css
Normal file
90
front/premium_store/src/styles/App.css
Normal file
@ -0,0 +1,90 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/*#505050*/
|
||||
|
||||
#root{
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background-color: #151719;
|
||||
background-image: url("../images/wot-is-4.jpg");
|
||||
background-size: cover;
|
||||
background-attachment: fixed;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.body{
|
||||
margin: 0; /* Убираем отступы */
|
||||
height: 100%; /* Высота страницы */
|
||||
}
|
||||
|
||||
.App{
|
||||
width: 1200px;
|
||||
}
|
||||
|
||||
.Group_create_level{
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
background-color: #FFE430;
|
||||
opacity: 0.8;
|
||||
border-radius: 10px;
|
||||
margin-top: 15px;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Card_list{
|
||||
padding: 15px;
|
||||
border: 5px solid;
|
||||
border-color: #14A76C;
|
||||
background-color: #151719;
|
||||
opacity: 0.9;
|
||||
border-radius: 10px;
|
||||
margin-top: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Main_head{
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
margin-top: 30px;
|
||||
border: 5px solid;
|
||||
border-color: #FF652F;
|
||||
border-radius: 10px;
|
||||
background-color: #151719;
|
||||
opacity: 0.9;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.Button_Main_Group{
|
||||
padding: 5px;
|
||||
border-color: #FF652F;
|
||||
border-radius: 10px;
|
||||
background-color: #FF652F;
|
||||
font-family: Courier, monospace;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.add-level-button{
|
||||
padding: 10px;
|
||||
margin-right: 15px;
|
||||
}
|
||||
|
||||
.Main-label{
|
||||
display: flex;
|
||||
padding-top: 16px;
|
||||
font-size: 7vw;
|
||||
font-variant: small-caps;
|
||||
font-stretch: ultra-expanded;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
color: #505050;
|
||||
-webkit-text-stroke-width: 3.0px;
|
||||
-webkit-text-stroke-color: #000000;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<App />
|
||||
//document.getElementById('root'); - для работы этого надо поставит запятую после <App/>
|
||||
//и делаем import 'react-dom', вместо 'react-dom/client'
|
||||
);
|
||||
|
2
spring_online_calculator/.gitignore
vendored
2
spring_online_calculator/.gitignore
vendored
@ -35,3 +35,5 @@ out/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
*.db
|
@ -1,10 +1,10 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'org.springframework.boot' version '2.7.8'
|
||||
id 'org.springframework.boot' version '2.6.5'
|
||||
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
|
||||
id 'java'
|
||||
}
|
||||
|
||||
group = 'com.example'
|
||||
group = 'ru.ulstu.is'
|
||||
version = '0.0.1-SNAPSHOT'
|
||||
sourceCompatibility = '17'
|
||||
|
||||
@ -12,9 +12,29 @@ repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||
implementation 'com.h2database:h2:2.1.210'
|
||||
|
||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||
implementation 'org.springframework.boot:spring-boot-devtools'
|
||||
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
|
||||
|
||||
implementation 'org.webjars:bootstrap:5.1.3'
|
||||
implementation 'org.webjars:jquery:3.6.0'
|
||||
implementation 'org.webjars:font-awesome:6.1.0'
|
||||
|
||||
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
|
||||
|
||||
implementation 'org.hibernate.validator:hibernate-validator'
|
||||
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'
|
||||
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
}
|
||||
|
||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
6
spring_online_calculator/gradlew
vendored
6
spring_online_calculator/gradlew
vendored
@ -205,12 +205,6 @@ set -- \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
if ! command -v xargs >/dev/null 2>&1
|
||||
then
|
||||
die "xargs is not available"
|
||||
fi
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
|
14
spring_online_calculator/gradlew.bat
vendored
14
spring_online_calculator/gradlew.bat
vendored
@ -14,7 +14,7 @@
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@ -25,7 +25,7 @@
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%"=="" set DIRNAME=.
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if %ERRORLEVEL% equ 0 goto execute
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@ -75,15 +75,13 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
set EXIT_CODE=%ERRORLEVEL%
|
||||
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||
exit /b %EXIT_CODE%
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
@ -1 +1 @@
|
||||
rootProject.name = 'spring_online_calculator'
|
||||
rootProject.name = 'premium_store'
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.example.spring_online_calculator;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringOnlineCalculatorApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringOnlineCalculatorApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package premium_store;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class PremiumStoreApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(PremiumStoreApplication.class, args);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package premium_store;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
//отключение Cors фильтра - не позволяет организовавыть взаимодействие с разных доменов
|
||||
@Configuration
|
||||
public class WebConfiguration implements WebMvcConfigurer {
|
||||
public static final String REST_API = "/api";
|
||||
|
||||
@Override
|
||||
public void addCorsMappings(CorsRegistry registry) {
|
||||
registry.addMapping("/**").allowedMethods("*");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.GameClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//класс, который соединяет танки клиента в одну строчку (нам так захотелось)
|
||||
public class ClientDTO {
|
||||
private long id;
|
||||
private String nickName;
|
||||
private String email;
|
||||
private Integer balance;
|
||||
private List<TankDTO> tanks;
|
||||
|
||||
public ClientDTO(){ }
|
||||
|
||||
public ClientDTO(GameClient gameClient){
|
||||
this.id = gameClient.getId();
|
||||
this.nickName = gameClient.getNickName();
|
||||
this.email = gameClient.getEmail();
|
||||
this.balance = gameClient.getBalance();
|
||||
this.tanks = gameClient.getTanks().stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNickName(){
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public String getEmail(){
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Integer getBalance(){
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Integer balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public List<TankDTO> getTanks(){
|
||||
return tanks;
|
||||
}
|
||||
|
||||
public Long getIdLastTanks(){
|
||||
return tanks.get(tanks.size() - 1).getId();
|
||||
}
|
||||
|
||||
public void setTanks(List<TankDTO> tanks) {
|
||||
this.tanks = tanks;
|
||||
}
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.Nation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class FullNationDTO {
|
||||
public Long id;
|
||||
public String nation;
|
||||
public List<TankDTO> tanks;
|
||||
|
||||
public FullNationDTO(){ }
|
||||
|
||||
public FullNationDTO(Nation nation){
|
||||
this.id = nation.getId();
|
||||
this.nation = nation.getNation();
|
||||
this.tanks = nation.getTanksOfThisNation().stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNation() {
|
||||
return nation;
|
||||
}
|
||||
|
||||
public void setNation(String nation) {
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
public List<TankDTO> getTanksOfThisNation() {
|
||||
return tanks;
|
||||
}
|
||||
|
||||
public void setTanks(List<TankDTO> tanks) {
|
||||
this.tanks = tanks;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.TankLevel;
|
||||
|
||||
public class LevelDTO {
|
||||
private Long id;
|
||||
private int level;
|
||||
|
||||
public LevelDTO(){}
|
||||
|
||||
public LevelDTO(TankLevel level){
|
||||
this.id = level.getId();
|
||||
this.level = level.getLevel();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public Long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getLevel(){
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.Nation;
|
||||
|
||||
public class SimpleNationDTO {
|
||||
private Long id;
|
||||
private String nation;
|
||||
|
||||
public SimpleNationDTO(){}
|
||||
|
||||
public SimpleNationDTO(Nation nation){
|
||||
this.id = nation.getId();
|
||||
this.nation = nation.getNation();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public Long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id){
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNation(){
|
||||
return nation;
|
||||
}
|
||||
|
||||
public void setNation(String nation){
|
||||
this.nation = nation;
|
||||
}
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
public class SortDTO {
|
||||
private String nation;
|
||||
private int firstLevel;
|
||||
private int secondLevel;
|
||||
|
||||
public SortDTO(){}
|
||||
|
||||
public SortDTO(String nation, int firstLevel, int secondLevel){
|
||||
this.nation = nation;
|
||||
this.firstLevel = firstLevel;
|
||||
this.secondLevel = secondLevel;
|
||||
}
|
||||
|
||||
public String getNation(){
|
||||
return nation;
|
||||
}
|
||||
|
||||
public int getFirstLevel() {
|
||||
return firstLevel;
|
||||
}
|
||||
|
||||
public int getSecondLevel() {
|
||||
return secondLevel;
|
||||
}
|
||||
|
||||
public void setNation(String nation){
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
public void setFirstLevel(int firstLevel){
|
||||
this.firstLevel = firstLevel;
|
||||
}
|
||||
|
||||
public void setSecondLevel(int secondLevel) {
|
||||
this.secondLevel = secondLevel;
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.GameClient;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//класс, который соединяет танки клиента в одну строчку (нам так захотелось)
|
||||
public class SupportClientDTO {
|
||||
private long id;
|
||||
private String nickName;
|
||||
private String email;
|
||||
private Integer balance;
|
||||
private Long tankId;
|
||||
|
||||
public SupportClientDTO(){ }
|
||||
|
||||
public SupportClientDTO(GameClient gameClient){
|
||||
this.id = gameClient.getId();
|
||||
this.nickName = gameClient.getNickName();
|
||||
this.email = gameClient.getEmail();
|
||||
this.balance = gameClient.getBalance();
|
||||
|
||||
if(gameClient.getTanks().size() >= 1){
|
||||
this.tankId = gameClient.getTanks().get(gameClient.getTanks().size() - 1).getId();
|
||||
}
|
||||
else {
|
||||
this.tankId = null;
|
||||
}
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getNickName(){
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName) {
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public String getEmail(){
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Integer getBalance(){
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Integer balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public Long getTankId(){
|
||||
return tankId;
|
||||
}
|
||||
|
||||
public void setTankId(Long tankId) {
|
||||
this.tankId = tankId;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.Tank;
|
||||
|
||||
public class SupportTankDTO {
|
||||
private long id;
|
||||
private String name;
|
||||
private Long nationId;
|
||||
private Long levelId;
|
||||
private int cost;
|
||||
|
||||
public SupportTankDTO(){}
|
||||
|
||||
public SupportTankDTO(Tank tank){
|
||||
this.id = tank.getId();
|
||||
this.nationId = tank.getNation().getId();
|
||||
this.levelId = tank.getLevel().getId();
|
||||
this.name = tank.getName();
|
||||
this.cost = tank.getCost();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public Long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getNationId(){
|
||||
return nationId;
|
||||
}
|
||||
|
||||
public void setNationId(Long nationId) {
|
||||
this.nationId = nationId;
|
||||
}
|
||||
|
||||
public Long getLevelId(){
|
||||
return levelId;
|
||||
}
|
||||
|
||||
public void setLevelId(Long levelId) {
|
||||
this.levelId = levelId;
|
||||
}
|
||||
|
||||
public int getCost(){
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCost(int cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
package premium_store.controller.DTO;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import premium_store.model.Tank;
|
||||
|
||||
public class TankDTO {
|
||||
private long id;
|
||||
private String name;
|
||||
private SimpleNationDTO nation;
|
||||
private LevelDTO level;
|
||||
private int cost;
|
||||
|
||||
public TankDTO(){}
|
||||
|
||||
public TankDTO(Tank tank){
|
||||
this.id = tank.getId();
|
||||
this.nation = new SimpleNationDTO(tank.getNation());
|
||||
this.level = new LevelDTO(tank.getLevel());
|
||||
this.name = tank.getName();
|
||||
this.cost = tank.getCost();
|
||||
}
|
||||
|
||||
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||
public long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SimpleNationDTO getNation(){
|
||||
return nation;
|
||||
}
|
||||
|
||||
public void setNation(SimpleNationDTO nation) {
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
public LevelDTO getLevel(){
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(LevelDTO level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public int getCost(){
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCost(int cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
}
|
@ -0,0 +1,91 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.controller.DTO.*;
|
||||
import premium_store.service.GameClientService;
|
||||
import premium_store.service.TankService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/client")
|
||||
public class ClientMvcController {
|
||||
private final GameClientService gameClientService;
|
||||
private final TankService tankService;
|
||||
|
||||
public ClientMvcController(GameClientService gameClientService, TankService tankService){
|
||||
this.gameClientService = gameClientService;
|
||||
this.tankService = tankService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getClients(Model model){
|
||||
model.addAttribute("clients",
|
||||
gameClientService.findAllClients().stream()
|
||||
.map(ClientDTO::new)
|
||||
.toList());
|
||||
|
||||
return "client";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editClient(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("supportClientDTO", new SupportClientDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("clientId", id);
|
||||
model.addAttribute("supportClientDTO", new SupportClientDTO(gameClientService.findClient(id)));
|
||||
}
|
||||
|
||||
List<TankDTO> tanks = tankService.findAllTanks().stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("tanks", tanks);
|
||||
|
||||
return "client-edit";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/tanksOfClient", "/tanksOfClient/{id}"})
|
||||
public String editTanksOfClient(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("clientDTO", new ClientDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("clientId", id);
|
||||
model.addAttribute("clientDTO", new ClientDTO(gameClientService.findClient(id)));
|
||||
}
|
||||
|
||||
return "tanks-of-client-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"", "/{id}"})
|
||||
public String saveClient(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid SupportClientDTO clientDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model){
|
||||
if(bindingResult.hasErrors()){
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "client-edit";
|
||||
}
|
||||
|
||||
if(id == null || id <= 0){
|
||||
gameClientService.addClient(clientDTO.getNickName(), clientDTO.getNickName(), clientDTO.getBalance());
|
||||
} else {
|
||||
gameClientService.updateClient(clientDTO);
|
||||
}
|
||||
|
||||
return "redirect:/client";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteClient(@PathVariable Long id){
|
||||
gameClientService.deleteClient(id);
|
||||
return "redirect:/tank";
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.WebConfiguration;
|
||||
import premium_store.controller.DTO.ClientDTO;
|
||||
import premium_store.service.GameClientService;
|
||||
import premium_store.service.TankService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(WebConfiguration.REST_API + "/client")
|
||||
public class GameClientController {
|
||||
private final GameClientService gameClientService;
|
||||
private final TankService tankService;
|
||||
|
||||
public GameClientController(GameClientService gameClientService, TankService tankService){
|
||||
this.gameClientService = gameClientService;
|
||||
this.tankService = tankService;
|
||||
}
|
||||
|
||||
//аннотация PathVariable связывает значения id из URL и Long id
|
||||
@GetMapping("/{id}")
|
||||
public ClientDTO getClient(@PathVariable Long id) {
|
||||
return new ClientDTO(gameClientService.findClient(id));
|
||||
}
|
||||
|
||||
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||
@GetMapping("/")
|
||||
public List<ClientDTO> getClients() {
|
||||
return gameClientService.findAllClients().stream()
|
||||
.map(ClientDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping("/")
|
||||
public ClientDTO createClient(@RequestParam("nickName") String nickName,
|
||||
@RequestParam("email") String email,
|
||||
@RequestParam("balance") Integer balance) {
|
||||
return new ClientDTO(gameClientService.addClient(nickName, email, balance));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public ClientDTO updateClient(@PathVariable Long id,
|
||||
@RequestParam("nickName") String nickName,
|
||||
@RequestParam("email") String email,
|
||||
@RequestParam("balance") Integer balance,
|
||||
@RequestParam("tankId") Long tankId) {
|
||||
return new ClientDTO(gameClientService.updateClient(id, nickName, email, balance, tankService.findTank(tankId)));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public ClientDTO deleteClient(@PathVariable Long id) {
|
||||
return new ClientDTO(gameClientService.deleteClient(id));
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.controller.DTO.FullNationDTO;
|
||||
import premium_store.controller.DTO.LevelDTO;
|
||||
import premium_store.controller.DTO.SimpleNationDTO;
|
||||
import premium_store.service.NationService;
|
||||
import premium_store.service.TankLevelService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/level")
|
||||
public class LevelMvcController {
|
||||
private final TankLevelService levelService;
|
||||
|
||||
public LevelMvcController(TankLevelService levelService){
|
||||
this.levelService = levelService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getLevels(Model model){
|
||||
model.addAttribute("levels",
|
||||
levelService.findAllLevels().stream()
|
||||
.map(LevelDTO::new)
|
||||
.toList());
|
||||
return "level";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editLevel(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("levelDTO", new LevelDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("levelId", id);
|
||||
model.addAttribute("levelDTO", new LevelDTO(levelService.findLevel(id)));
|
||||
}
|
||||
|
||||
return "level-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"", "/{id}"})
|
||||
public String saveLevel(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid LevelDTO levelDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model){
|
||||
if(bindingResult.hasErrors()){
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "level-edit";
|
||||
}
|
||||
|
||||
if(id == null || id <= 0){
|
||||
levelService.addLevel(levelDTO.getLevel());
|
||||
} else {
|
||||
levelService.updateLevel(id, levelDTO.getLevel());
|
||||
}
|
||||
|
||||
return "redirect:/level";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteLevel(@PathVariable Long id){
|
||||
levelService.deleteLevel(id);
|
||||
return "redirect:/level";
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.WebConfiguration;
|
||||
import premium_store.controller.DTO.FullNationDTO;
|
||||
import premium_store.service.NationService;
|
||||
import premium_store.service.TankService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//привязываем наш контроллер к придуманному корневому URL благодаря аннотациям
|
||||
//здесь происходит внедрение зависимости нашего сервиса
|
||||
//так же здесь прописываем вызовы методов CRUD в привязке к URL
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
@RequestMapping(WebConfiguration.REST_API + "/nation")
|
||||
public class NationController {
|
||||
private final NationService nationService;
|
||||
private final TankService tankService;
|
||||
|
||||
public NationController(NationService nationService, TankService tankService){
|
||||
this.nationService = nationService;
|
||||
this.tankService = tankService;
|
||||
}
|
||||
|
||||
//аннотация PathVariable связывает значения id из URL и Long id
|
||||
@GetMapping("/{id}")
|
||||
public FullNationDTO getNation(@PathVariable Long id) {
|
||||
return new FullNationDTO(nationService.findNation(id));
|
||||
}
|
||||
|
||||
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||
@GetMapping("/")
|
||||
public List<FullNationDTO> getNations() {
|
||||
return nationService.findAllNations().stream()
|
||||
.map(FullNationDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping("/")
|
||||
public FullNationDTO createNation(@RequestParam("nation") String nation) {
|
||||
return new FullNationDTO(nationService.addNation(nation));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public FullNationDTO updateNation(@PathVariable Long id,
|
||||
@RequestParam("nation") String nation,
|
||||
@RequestParam(value = "tankId", required = false) Long tankId ) {
|
||||
return new FullNationDTO(nationService.updateNation(id, nation, (tankId > 0) ? tankService.findTank(tankId) : null));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public FullNationDTO deleteNation(@PathVariable Long id) {
|
||||
return new FullNationDTO(nationService.deleteNation(id));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,82 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import net.bytebuddy.implementation.bind.MethodDelegationBinder;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.controller.DTO.FullNationDTO;
|
||||
import premium_store.controller.DTO.SimpleNationDTO;
|
||||
import premium_store.service.NationService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/nation")
|
||||
public class NationMvcController {
|
||||
private final NationService nationService;
|
||||
|
||||
public NationMvcController(NationService nationService){
|
||||
this.nationService = nationService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getNations(Model model){
|
||||
model.addAttribute("nations",
|
||||
nationService.findAllNations().stream()
|
||||
.map(FullNationDTO::new)
|
||||
.toList());
|
||||
return "nation";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editNation(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("simpleNationDTO", new SimpleNationDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("nationId", id);
|
||||
model.addAttribute("simpleNationDTO", new SimpleNationDTO(nationService.findNation(id)));
|
||||
}
|
||||
|
||||
return "nation-edit";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/editTank", "/editTank/{id}"})
|
||||
public String editTankNation(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("fullNationDTO", new FullNationDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("nationId", id);
|
||||
model.addAttribute("fullNationDTO", new FullNationDTO(nationService.findNation(id)));
|
||||
}
|
||||
|
||||
return "nation-tank-edit";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"", "/{id}"})
|
||||
public String saveNation(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid SimpleNationDTO simpleNationDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model){
|
||||
if(bindingResult.hasErrors()){
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "nation-edit";
|
||||
}
|
||||
|
||||
if(id == null || id <= 0){
|
||||
nationService.addNation(simpleNationDTO.getNation());
|
||||
} else {
|
||||
nationService.updateNation(id, simpleNationDTO.getNation(), null);
|
||||
}
|
||||
|
||||
return "redirect:/nation";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteNation(@PathVariable Long id){
|
||||
nationService.deleteNation(id);
|
||||
return "redirect:/nation";
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.WebConfiguration;
|
||||
import premium_store.controller.DTO.TankDTO;
|
||||
import premium_store.service.NationService;
|
||||
import premium_store.service.TankLevelService;
|
||||
import premium_store.service.TankService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@CrossOrigin
|
||||
@RequestMapping(WebConfiguration.REST_API + "/tank")
|
||||
public class TankController {
|
||||
private final TankService tankService;
|
||||
private final TankLevelService tankLevelService;
|
||||
private final NationService nationService;
|
||||
|
||||
public TankController(TankService tankService, TankLevelService tankLevelService, NationService nationService){
|
||||
this.tankService = tankService;
|
||||
this.tankLevelService = tankLevelService;
|
||||
this.nationService = nationService;
|
||||
}
|
||||
|
||||
//аннотация PathVariable связывает значения id из URL и Long id
|
||||
@GetMapping("/{id}")
|
||||
public TankDTO getTank(@PathVariable Long id) {
|
||||
return new TankDTO(tankService.findTank(id));
|
||||
}
|
||||
|
||||
//с помощью Java Stream преобразуем набор пришедших данных в объекты TankDTO
|
||||
@GetMapping("/")
|
||||
public List<TankDTO> getTanks() {
|
||||
return tankService.findAllTanks().stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@GetMapping("/filteredList/")
|
||||
public List<TankDTO> getFilteredTanks(@RequestParam("nation") String nation,
|
||||
@RequestParam("firstLevel") int firstLevel,
|
||||
@RequestParam("secondLevel") int secondLevel) {
|
||||
return tankService.findListTank(nation, firstLevel, secondLevel).stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping("/")
|
||||
public TankDTO createTank(@RequestParam("firstName") String name,
|
||||
@RequestParam("nationId") Long nationId,
|
||||
@RequestParam("levelId") Long tankLevelId,
|
||||
@RequestParam("cost") int cost
|
||||
) {
|
||||
return new TankDTO(tankService.addTank(name, nationService.findNation(nationId), tankLevelService.findLevel(tankLevelId), cost));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public TankDTO updateTank(@PathVariable Long id,
|
||||
@RequestParam("firstName") String name,
|
||||
@RequestParam("nationId") Long nationId,
|
||||
@RequestParam("levelId") Long tankLevelId,
|
||||
@RequestParam("cost") int cost
|
||||
) {
|
||||
return new TankDTO(tankService.updateTank(id, name, nationService.findNation(nationId), tankLevelService.findLevel(tankLevelId), cost));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public TankDTO deleteTank(@PathVariable Long id) {
|
||||
return new TankDTO(tankService.deleteTank(id));
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.WebConfiguration;
|
||||
import premium_store.controller.DTO.LevelDTO;
|
||||
import premium_store.service.TankLevelService;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
//привязываем наш контроллер к придуманному корневому URL благодаря аннотациям
|
||||
//здесь происходит внедрение зависимости нашего сервиса
|
||||
//так же здесь прописываем вызовы методов CRUD в привязке к URL
|
||||
@RestController
|
||||
@RequestMapping(WebConfiguration.REST_API + "/level")
|
||||
public class TankLevelController {
|
||||
private final TankLevelService tankLevelService;
|
||||
|
||||
public TankLevelController(TankLevelService tankLevelService){
|
||||
this.tankLevelService = tankLevelService;
|
||||
}
|
||||
|
||||
//аннотация PathVariable связывает значения id из URL и Long id
|
||||
@GetMapping("/{id}")
|
||||
public LevelDTO getLevel(@PathVariable Long id) {
|
||||
return new LevelDTO(tankLevelService.findLevel(id));
|
||||
}
|
||||
|
||||
//с помощью Java Stream преобразуем набор пришедших данных в объекты StudentDto
|
||||
@GetMapping("/")
|
||||
public List<LevelDTO> getLevels() {
|
||||
return tankLevelService.findAllLevels().stream()
|
||||
.map(LevelDTO::new)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@PostMapping("/")
|
||||
public LevelDTO createLevel(@RequestParam("Level") int level) {
|
||||
return new LevelDTO(tankLevelService.addLevel(level));
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public LevelDTO updateLevel(@PathVariable Long id,
|
||||
@RequestParam("Level") int level) {
|
||||
return new LevelDTO(tankLevelService.updateLevel(id, level));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public LevelDTO deleteLevel(@PathVariable Long id) {
|
||||
return new LevelDTO(tankLevelService.deleteLevel(id));
|
||||
}
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package premium_store.controller.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import premium_store.controller.DTO.*;
|
||||
import premium_store.service.NationService;
|
||||
import premium_store.service.TankLevelService;
|
||||
import premium_store.service.TankService;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@RequestMapping("/tank")
|
||||
public class TankMvcController {
|
||||
private final TankService tankService;
|
||||
private final NationService nationService;
|
||||
private final TankLevelService tankLevelService;
|
||||
|
||||
public TankMvcController(TankService tankService, NationService nationService, TankLevelService tankLevelService){
|
||||
this.tankService = tankService;
|
||||
this.nationService = nationService;
|
||||
this.tankLevelService = tankLevelService;
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getTanks(Model model){
|
||||
model.addAttribute("tanks",
|
||||
tankService.findAllTanks().stream()
|
||||
.map(TankDTO::new)
|
||||
.toList());
|
||||
|
||||
List<SimpleNationDTO> nations = nationService.findAllNations().stream()
|
||||
.map(SimpleNationDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("nations", nations);
|
||||
|
||||
List<LevelDTO> levels = tankLevelService.findAllLevels().stream()
|
||||
.map(LevelDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("levels", levels);
|
||||
|
||||
model.addAttribute("sortDTO", new SortDTO());
|
||||
|
||||
return "tank";
|
||||
}
|
||||
|
||||
@GetMapping(value = {"/edit", "/edit/{id}"})
|
||||
public String editTank(@PathVariable(required = false) Long id, Model model){
|
||||
if(id == null || id <= 0){
|
||||
model.addAttribute("supportTankDTO", new SupportTankDTO());
|
||||
}
|
||||
else {
|
||||
model.addAttribute("tankId", id);
|
||||
model.addAttribute("supportTankDTO", new SupportTankDTO(tankService.findTank(id)));
|
||||
}
|
||||
|
||||
List<SimpleNationDTO> nations = nationService.findAllNations().stream()
|
||||
.map(SimpleNationDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("nations", nations);
|
||||
|
||||
List<LevelDTO> levels = tankLevelService.findAllLevels().stream()
|
||||
.map(LevelDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("levels", levels);
|
||||
|
||||
return "tank-edit";
|
||||
}
|
||||
|
||||
@GetMapping("/filteredList")
|
||||
public String getFilteredTanks(@ModelAttribute SortDTO sortDTO,
|
||||
Model model) {
|
||||
List<TankDTO> tanks = tankService.findListTank(sortDTO.getNation(), sortDTO.getFirstLevel(), sortDTO.getSecondLevel()).stream()
|
||||
.map(TankDTO::new)
|
||||
.toList();
|
||||
|
||||
model.addAttribute("tanks", tanks);
|
||||
|
||||
return "filter";
|
||||
}
|
||||
|
||||
@PostMapping(value = {"", "/{id}"})
|
||||
public String saveTank(@PathVariable(required = false) Long id,
|
||||
@ModelAttribute @Valid SupportTankDTO tankDTO,
|
||||
BindingResult bindingResult,
|
||||
Model model){
|
||||
if(bindingResult.hasErrors()){
|
||||
model.addAttribute("errors", bindingResult.getAllErrors());
|
||||
return "tank-edit";
|
||||
}
|
||||
|
||||
if(id == null || id <= 0){
|
||||
tankService.addTank(tankDTO);
|
||||
} else {
|
||||
tankService.updateTank(tankDTO);
|
||||
}
|
||||
|
||||
return "redirect:/tank";
|
||||
}
|
||||
|
||||
@PostMapping("/delete/{id}")
|
||||
public String deleteTank(@PathVariable Long id){
|
||||
tankService.deleteTank(id);
|
||||
return "redirect:/tank";
|
||||
}
|
||||
}
|
@ -0,0 +1,103 @@
|
||||
package premium_store.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@Table(name = "GAMECLIENTS")
|
||||
public class GameClient {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "nickName", nullable = false, length = 255)
|
||||
private String nickName;
|
||||
|
||||
@Column(name = "email", nullable = false, length = 255)
|
||||
private String email;
|
||||
|
||||
@Column(name = "balance")
|
||||
private Integer balance;
|
||||
|
||||
@ManyToMany(fetch = FetchType.EAGER)
|
||||
private List<Tank> tanks = new ArrayList<>();
|
||||
|
||||
public GameClient(){ }
|
||||
|
||||
public GameClient(String nickName, String email, Integer balance){
|
||||
this.nickName = nickName;
|
||||
this.email = email;
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public Long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getNickName(){
|
||||
return nickName;
|
||||
}
|
||||
|
||||
public void setNickName(String nickName){
|
||||
this.nickName = nickName;
|
||||
}
|
||||
|
||||
public String getEmail(){
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email){
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public Integer getBalance(){
|
||||
return balance;
|
||||
}
|
||||
|
||||
public void setBalance(Integer balance){
|
||||
this.balance = balance;
|
||||
}
|
||||
|
||||
public List<Tank> getTanks(){
|
||||
return tanks;
|
||||
}
|
||||
|
||||
public void setTanks(Tank tank){
|
||||
this.tanks.add(tank);
|
||||
}
|
||||
|
||||
//метод для сравнения
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
GameClient gameClient = (GameClient) o;
|
||||
|
||||
return Objects.equals(id, gameClient.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
//преобразование данных по объекту в строчку
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Client{" +
|
||||
"id=" + id +
|
||||
", nickName='" + nickName + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
", balance='" + balance + '\'' +
|
||||
", tanks='" + tanks.stream().map(Object::toString).collect(Collectors.joining(", ")) + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package premium_store.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@Table(name = "NATIONS")
|
||||
public class Nation {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "nation")
|
||||
private String nation;
|
||||
|
||||
@OneToMany(mappedBy = "nation", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
|
||||
private List<Tank> tanksOfThisNation = new ArrayList<>();
|
||||
|
||||
public Nation() {
|
||||
}
|
||||
|
||||
public Nation(String nation) {
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
//возвращает id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
//возвращает нацию
|
||||
public String getNation() {
|
||||
return nation;
|
||||
}
|
||||
|
||||
public void setNation(String nation) {
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
public List<Tank> getTanksOfThisNation(){
|
||||
return tanksOfThisNation;
|
||||
}
|
||||
|
||||
public void setTanksOfThisNation(Tank newTank){
|
||||
this.tanksOfThisNation.add(newTank);
|
||||
}
|
||||
|
||||
//метод для сравнения
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
Nation nation = (Nation) o;
|
||||
|
||||
return Objects.equals(id, nation.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
//преобразование данных по объекту в строчку
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Nation{" +
|
||||
"id=" + id +
|
||||
", nation='" + nation + '\'' +
|
||||
", tanksOfThisNation='" + tanksOfThisNation.stream().map(Object::toString).collect(Collectors.joining(", ")) + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,101 @@
|
||||
package premium_store.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.Objects;
|
||||
|
||||
@Entity
|
||||
@Table(name = "TANKS")
|
||||
public class Tank {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "nation")
|
||||
private Nation nation;
|
||||
|
||||
@ManyToOne(fetch = FetchType.EAGER)
|
||||
@JoinColumn(name = "tankLevel")
|
||||
private TankLevel tankLevel;
|
||||
|
||||
@Column(nullable = false)
|
||||
private int cost;
|
||||
|
||||
public Tank() {
|
||||
}
|
||||
|
||||
public Tank(String name, Nation nation, TankLevel tankLevel, int cost) {
|
||||
this.name = name;
|
||||
this.nation = nation;
|
||||
this.tankLevel = tankLevel;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public Long getId(){
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public void setCost(int cost) {
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
public TankLevel getLevel() {
|
||||
return tankLevel;
|
||||
}
|
||||
|
||||
public void setLevel(TankLevel tankLevel) {
|
||||
this.tankLevel = tankLevel;
|
||||
}
|
||||
|
||||
public Nation getNation() {
|
||||
return nation;
|
||||
}
|
||||
|
||||
public void setNation(Nation nation) {
|
||||
this.nation = nation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
if (!(o instanceof Tank tank)) return false;
|
||||
|
||||
return Objects.equals(getId(), tank.getId()) && Objects.equals(getName(), tank.getName())
|
||||
&& Objects.equals(getCost(), tank.getCost())
|
||||
&& Objects.equals(getLevel(), tank.getLevel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
//преобразование данных по объекту в строчку
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Tank{" +
|
||||
"id=" + id +
|
||||
", name='" + name + '\'' +
|
||||
", nation='" + nation.getNation() + '\'' +
|
||||
", level='" + tankLevel.getLevel() + '\'' +
|
||||
", cost='" + cost + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,64 @@
|
||||
package premium_store.model;
|
||||
|
||||
import javax.persistence.*;
|
||||
import java.util.*;
|
||||
|
||||
@Entity
|
||||
@Table(name = "TANKLEVELS")
|
||||
public class TankLevel {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Column(name = "level", nullable = false)
|
||||
private int level;
|
||||
|
||||
public TankLevel() {
|
||||
}
|
||||
|
||||
public TankLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
//возвращает id
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
//возвращает нацию
|
||||
public int getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(int level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
//метод для сравнения
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
TankLevel tankLevel = (TankLevel) o;
|
||||
|
||||
return Objects.equals(id, tankLevel.id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id);
|
||||
}
|
||||
|
||||
//преобразование данных по объекту в строчку
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Level{" +
|
||||
"id=" + id +
|
||||
", level='" + level + '}';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package premium_store.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import premium_store.model.GameClient;
|
||||
|
||||
public interface GameClientRepository extends JpaRepository<GameClient, Long> {
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package premium_store.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import premium_store.model.Nation;
|
||||
|
||||
//класс для взаимодействия с БД вместо низкоуровневого EntityManager
|
||||
//передаём тип класса и тип id его элементов
|
||||
public interface NationRepository extends JpaRepository<Nation, Long> {
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package premium_store.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import premium_store.model.TankLevel;
|
||||
|
||||
//класс для взаимодействия с БД вместо низкоуровневого EntityManager
|
||||
//передаём тип класса и тип id его элементов
|
||||
public interface TankLevelRepository extends JpaRepository<TankLevel, Long> {
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package premium_store.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import premium_store.model.Tank;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface TankRepository extends JpaRepository<Tank, Long> {
|
||||
@Query("SELECT t FROM Tank t WHERE t.nation.nation = :nation AND t.tankLevel.level BETWEEN :llevelid AND :l2levelid")
|
||||
List<Tank> checkNationAndLevel(
|
||||
@Param("nation") String nation,
|
||||
@Param("llevelid") int levelOne,
|
||||
@Param("l2levelid") int levelTwo);
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package premium_store.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import premium_store.controller.DTO.ClientDTO;
|
||||
import premium_store.controller.DTO.SupportClientDTO;
|
||||
import premium_store.model.GameClient;
|
||||
import premium_store.model.Tank;
|
||||
import premium_store.repository.GameClientRepository;
|
||||
import premium_store.repository.TankRepository;
|
||||
import premium_store.service.exception.ClientNotFoundException;
|
||||
import premium_store.util.validation.ValidatorUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class GameClientService {
|
||||
private final GameClientRepository gameClientRepository;
|
||||
private final TankRepository tankRepository;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public GameClientService(GameClientRepository gameClientRepository, TankRepository tankRepository, ValidatorUtil validatorUtil){
|
||||
this.gameClientRepository = gameClientRepository;
|
||||
this.tankRepository = tankRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GameClient addClient(String newNickName, String newEmail, Integer newBallance) {
|
||||
final GameClient gameClient = new GameClient(newNickName, newEmail, newBallance);
|
||||
validatorUtil.validate(gameClient);
|
||||
|
||||
return gameClientRepository.save(gameClient);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public GameClient findClient(Long id) {
|
||||
final Optional<GameClient> client = gameClientRepository.findById(id);
|
||||
|
||||
return client.orElseThrow(() -> new ClientNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<GameClient> findAllClients() {
|
||||
return gameClientRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GameClient updateClient(Long id, String newNickName, String newEmail, Integer newBalance, Tank newTank) {
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException("Invalid id");
|
||||
}
|
||||
|
||||
final GameClient currentGameClient = findClient(id);
|
||||
|
||||
if (StringUtils.hasText(newNickName)){
|
||||
currentGameClient.setNickName(newNickName);
|
||||
}
|
||||
|
||||
if(StringUtils.hasText(newEmail)){
|
||||
currentGameClient.setEmail(newEmail);
|
||||
}
|
||||
|
||||
if(newBalance != null){
|
||||
currentGameClient.setBalance(newBalance);
|
||||
}
|
||||
|
||||
if(newTank != null){
|
||||
currentGameClient.setTanks(newTank);
|
||||
}
|
||||
|
||||
return gameClientRepository.save(currentGameClient);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GameClient updateClient(SupportClientDTO clientDTO) {
|
||||
if (clientDTO.getId() <= 0) {
|
||||
throw new IllegalArgumentException("Invalid id");
|
||||
}
|
||||
|
||||
final GameClient currentGameClient = findClient(clientDTO.getId());
|
||||
|
||||
currentGameClient.setNickName(clientDTO.getNickName());
|
||||
currentGameClient.setEmail(clientDTO.getEmail());
|
||||
currentGameClient.setBalance(clientDTO.getBalance());
|
||||
|
||||
if(clientDTO.getTankId() != null){
|
||||
currentGameClient.setTanks(tankRepository.getById(clientDTO.getTankId()));
|
||||
}
|
||||
|
||||
return gameClientRepository.save(currentGameClient);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public GameClient deleteClient(Long id) {
|
||||
final GameClient currentGameClient = findClient(id);
|
||||
gameClientRepository.delete(currentGameClient);
|
||||
|
||||
return currentGameClient;
|
||||
}
|
||||
|
||||
//прямой sql-запрос на удаление всех записей в таблице
|
||||
@Transactional
|
||||
public void deleteAllClients() {
|
||||
gameClientRepository.deleteAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package premium_store.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import premium_store.model.Nation;
|
||||
import premium_store.model.Tank;
|
||||
import premium_store.repository.NationRepository;
|
||||
import premium_store.service.exception.NationNotFoundException;
|
||||
import premium_store.util.validation.ValidatorUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class NationService {
|
||||
private final NationRepository nationRepository;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public NationService(NationRepository nationRepository, ValidatorUtil validatorUtil){
|
||||
this.nationRepository = nationRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Nation addNation(String nameNation){
|
||||
final Nation nation = new Nation(nameNation);
|
||||
validatorUtil.validate(nation);
|
||||
|
||||
return nationRepository.save(nation);
|
||||
}
|
||||
|
||||
//здесь используем Optional - спец. тип данных, позволяющий определять, вернулось ли что-то при вызове метода, или вернулся null
|
||||
@Transactional(readOnly = true)
|
||||
public Nation findNation(Long id){
|
||||
final Optional<Nation> nation = nationRepository.findById(id);
|
||||
|
||||
//благодаря Optional можем вызвать orElseThrow, который в случае null сделает проброс кастомного исключения
|
||||
return nation.orElseThrow(() -> new NationNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Nation> findAllNations() {
|
||||
return nationRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Nation updateNation(Long id, String newNation, Tank newTank) {
|
||||
if(id <= 0){
|
||||
throw new IllegalArgumentException(String.format("Incorrect id: [%s]", id));
|
||||
}
|
||||
|
||||
final Nation currentNation = findNation(id);
|
||||
|
||||
if (StringUtils.hasText(newNation)) {
|
||||
currentNation.setNation(newNation);
|
||||
}
|
||||
|
||||
if(newTank != null){
|
||||
currentNation.setTanksOfThisNation(newTank);
|
||||
}
|
||||
|
||||
return nationRepository.save(currentNation);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Nation deleteNation(Long id) {
|
||||
final Nation currentNation = findNation(id);
|
||||
nationRepository.delete(currentNation);
|
||||
|
||||
return currentNation;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAllNations() {
|
||||
nationRepository.deleteAll();
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package premium_store.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import premium_store.model.TankLevel;
|
||||
import premium_store.repository.TankLevelRepository;
|
||||
import premium_store.service.exception.LevelNotFoundException;
|
||||
import premium_store.util.validation.ValidatorUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
//сервис после удаления EntityManager и добавления нашего репозитория. То есть у него уже все методы работы с полями прописаны за нас?
|
||||
@Service
|
||||
public class TankLevelService {
|
||||
private final TankLevelRepository tankLevelRepository;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public TankLevelService(TankLevelRepository tankLevelRepository, ValidatorUtil validatorUtil){
|
||||
this.tankLevelRepository = tankLevelRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TankLevel addLevel(int newLevel) {
|
||||
final TankLevel tankLevel = new TankLevel(newLevel);
|
||||
validatorUtil.validate(tankLevel);
|
||||
|
||||
return tankLevelRepository.save(tankLevel);
|
||||
}
|
||||
|
||||
//здесь используем Optional - спец. тип данных, позволяющий определять, вернулось ли что-то при вызове метода, или вернулся null
|
||||
@Transactional(readOnly = true)
|
||||
public TankLevel findLevel(Long id) {
|
||||
final Optional<TankLevel> level = tankLevelRepository.findById(id);
|
||||
|
||||
//благодаря Optional можем вызвать orElseThrow, который в случае null сделает проброс кастомного исключения
|
||||
return level.orElseThrow(() -> new LevelNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<TankLevel> findAllLevels() {
|
||||
return tankLevelRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TankLevel updateLevel(Long id, int newLevel) {
|
||||
final TankLevel currentTankLevel = findLevel(id);
|
||||
currentTankLevel.setLevel(newLevel);
|
||||
validatorUtil.validate(currentTankLevel);
|
||||
|
||||
return tankLevelRepository.save(currentTankLevel);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public TankLevel deleteLevel(Long id) {
|
||||
final TankLevel currentTankLevel = findLevel(id);
|
||||
tankLevelRepository.delete(currentTankLevel);
|
||||
|
||||
return currentTankLevel;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void deleteAllLevels() {
|
||||
tankLevelRepository.deleteAll();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,126 @@
|
||||
package premium_store.service;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import premium_store.controller.DTO.SupportTankDTO;
|
||||
import premium_store.controller.DTO.TankDTO;
|
||||
import premium_store.model.TankLevel;
|
||||
import premium_store.model.Nation;
|
||||
import premium_store.model.Tank;
|
||||
import premium_store.repository.NationRepository;
|
||||
import premium_store.repository.TankLevelRepository;
|
||||
import premium_store.repository.TankRepository;
|
||||
import premium_store.service.exception.TankNotFoundException;
|
||||
import premium_store.util.validation.ValidatorUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class TankService {
|
||||
private final TankRepository tankRepository;
|
||||
private final NationRepository nationRepository;
|
||||
private final TankLevelRepository levelRepository;
|
||||
private final ValidatorUtil validatorUtil;
|
||||
|
||||
public TankService(TankRepository tankRepository, NationRepository nationRepository, TankLevelRepository levelRepository, ValidatorUtil validatorUtil){
|
||||
this.tankRepository = tankRepository;
|
||||
this.nationRepository = nationRepository;
|
||||
this.levelRepository = levelRepository;
|
||||
this.validatorUtil = validatorUtil;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Tank addTank(String newName, Nation newNation, TankLevel newTankLevel, int newCost) {
|
||||
final Tank tank = new Tank(newName, newNation, newTankLevel, newCost);
|
||||
validatorUtil.validate(tank);
|
||||
|
||||
return tankRepository.save(tank);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Tank addTank(SupportTankDTO tankDTO) {
|
||||
final Tank tank = new Tank(tankDTO.getName(), nationRepository.getById(tankDTO.getNationId()),
|
||||
levelRepository.getById(tankDTO.getLevelId()), tankDTO.getCost());
|
||||
validatorUtil.validate(tank);
|
||||
|
||||
return tankRepository.save(tank);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public Tank findTank(Long id) {
|
||||
final Optional<Tank> tank = tankRepository.findById(id);
|
||||
|
||||
return tank.orElseThrow(() -> new TankNotFoundException(id));
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Tank> findAllTanks() {
|
||||
return tankRepository.findAll();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Tank updateTank(Long id, String newName, Nation newNation,
|
||||
TankLevel newLevel, int newCost) {
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException("Invalid id");
|
||||
}
|
||||
|
||||
final Tank currentTank = findTank(id);
|
||||
|
||||
if (StringUtils.hasText(newName)){
|
||||
currentTank.setName(newName);
|
||||
}
|
||||
|
||||
if(newNation != null){
|
||||
currentTank.setNation(newNation);
|
||||
}
|
||||
|
||||
if(newLevel != null){
|
||||
currentTank.setLevel(newLevel);
|
||||
}
|
||||
|
||||
if(newCost > 0){
|
||||
currentTank.setCost(newCost);
|
||||
}
|
||||
|
||||
return tankRepository.save(currentTank);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Tank updateTank(SupportTankDTO tankDTO) {
|
||||
if (tankDTO.getId() <= 0) {
|
||||
throw new IllegalArgumentException("Invalid id");
|
||||
}
|
||||
|
||||
final Tank currentTank = findTank(tankDTO.getId());
|
||||
|
||||
currentTank.setName(tankDTO.getName());
|
||||
currentTank.setNation(nationRepository.getById(tankDTO.getNationId()));
|
||||
currentTank.setLevel(levelRepository.getById(tankDTO.getLevelId()));
|
||||
currentTank.setCost(tankDTO.getCost());
|
||||
|
||||
return tankRepository.save(currentTank);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public Tank deleteTank(Long id) {
|
||||
final Tank currentTank = findTank(id);
|
||||
tankRepository.delete(currentTank);
|
||||
|
||||
return currentTank;
|
||||
}
|
||||
|
||||
//запрос на удаление всех записей в таблице
|
||||
@Transactional
|
||||
public void deleteAllTanks() {
|
||||
tankRepository.deleteAll();
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public List<Tank> findListTank(String nationName, int levelFirst, int levelSecond) {
|
||||
return tankRepository.checkNationAndLevel(nationName, levelFirst, levelSecond);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package premium_store.service.exception;
|
||||
|
||||
public class ClientNotFoundException extends RuntimeException {
|
||||
public ClientNotFoundException(Long id) {
|
||||
super(String.format("Client with id [%s] is not found", id));
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package premium_store.service.exception;
|
||||
|
||||
//класс-обработчик ошибки, когда вытаемся вытащить студента из бд по некорректному id
|
||||
//наследуем от RuntimeException, т. к. он позволяет его проще вызывать
|
||||
public class LevelNotFoundException extends RuntimeException {
|
||||
public LevelNotFoundException(Long id) {
|
||||
super(String.format("Level with id [%s] is not found", id));
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
package premium_store.service.exception;
|
||||
|
||||
public class NationNotFoundException extends RuntimeException {
|
||||
public NationNotFoundException(Long id) {
|
||||
super(String.format("Nation with id [%s] is not found", id));
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package premium_store.service.exception;
|
||||
|
||||
public class TankNotFoundException extends RuntimeException {
|
||||
public TankNotFoundException(Long id) {
|
||||
super(String.format("Tank with id [%s] is not found", id));
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package premium_store.util.error;
|
||||
|
||||
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 org.springframework.web.bind.annotation.RestController;
|
||||
import premium_store.service.exception.ClientNotFoundException;
|
||||
import premium_store.service.exception.LevelNotFoundException;
|
||||
import premium_store.service.exception.NationNotFoundException;
|
||||
import premium_store.service.exception.TankNotFoundException;
|
||||
import premium_store.util.validation.ValidationException;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
//контроллер для обработки разнообразных ошибок при работе с запросами к БД
|
||||
@ControllerAdvice(annotations = RestController.class)
|
||||
public class AdviceController {
|
||||
//метод handleException будет вызываться при возникновении исключений типа LevelNotFoundException и т. д.
|
||||
@ExceptionHandler({
|
||||
LevelNotFoundException.class,
|
||||
NationNotFoundException.class,
|
||||
ClientNotFoundException.class,
|
||||
TankNotFoundException.class,
|
||||
ValidationException.class
|
||||
})
|
||||
public ResponseEntity<Object> handleException(Throwable e) {
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
||||
//при исключении автоматической валидации данных
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<Object> handleBindException(MethodArgumentNotValidException e) {
|
||||
final ValidationException validationException = new ValidationException(
|
||||
e.getBindingResult().getAllErrors().stream()
|
||||
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||
.collect(Collectors.toSet()));
|
||||
|
||||
return handleException(validationException);
|
||||
}
|
||||
|
||||
//обработка неизвестных ошибок
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<Object> handleUnknownException(Throwable e) {
|
||||
e.printStackTrace();
|
||||
|
||||
return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package premium_store.util.validation;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
//класс для передачи списка ошибок, если они возникают
|
||||
public class ValidationException extends RuntimeException {
|
||||
public ValidationException(Set<String> errors) {
|
||||
super(String.join("\n", errors));
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user