как всегда ничего не работает (」°ロ°)」

This commit is contained in:
Inohara 2023-05-01 21:59:28 +04:00
parent c6889698bf
commit 0a3a5aedbb
18 changed files with 383 additions and 29 deletions

View File

@ -19,6 +19,14 @@ jar{
dependencies { dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-web'
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 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210' implementation 'com.h2database:h2:2.1.210'
implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-validation'

View File

@ -4,6 +4,7 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration

View File

@ -6,7 +6,7 @@ import java.util.List;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/product") @RequestMapping("/api/product")
public class ProductController { public class ProductController {
private final ProductService productService; private final ProductService productService;

View File

@ -10,6 +10,8 @@ public class ProductDto {
private double cost; private double cost;
private List<_Order> orders; private List<_Order> orders;
public ProductDto() {}
public ProductDto(Product product) { public ProductDto(Product product) {
this.id = product.getId(); this.id = product.getId();
this.name = product.getName(); this.name = product.getName();

View File

@ -0,0 +1,57 @@
package com.example.demo.supply.Product;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/product")
public class ProductMvcController {
private final ProductService productService;
public ProductMvcController(ProductService productService){ this.productService = productService;}
@GetMapping
public String getProducts(Model model) {
model.addAttribute("products",
productService.findAllProducts().stream().map(ProductDto::new).toList());
return "product";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editProduct(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("productDto", new ProductDto());
} else {
model.addAttribute("productId", id);
model.addAttribute("productDto", new ProductDto(productService.findProduct(id)));
}
return "product-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveProduct(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ProductDto productDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "product-edit";
}
if (id == null || id <= 0) {
productService.addProduct(productDto.getName(), productDto.getCost());
} else {
productService.updateProduct(id, productDto.getName(), productDto.getCost());
}
return "redirect:/product";
}
@PostMapping("/delete/{id}")
public String deleteProduct(@PathVariable Long id) {
productService.deleteProduct(id);
return "redirect:/product";
}
}

View File

@ -1,26 +0,0 @@
package com.example.demo.supply.Supplier;
import com.example.demo.supply.Product.ProductDto;
import com.example.demo.supply.Product.ProductService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/product")
public class ProductMvcController {
private final ProductService productService;
public ProductMvcController(ProductService productService){ this.productService = productService;}
@GetMapping("/")
public String getProducts(Model model) {
model.addAttribute("students",
productService.findAllProducts().stream().map(ProductDto::new).toList());
return "students";
}
}

View File

@ -6,7 +6,7 @@ import java.util.List;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/supplier") @RequestMapping("/api/supplier")
public class SupplierController { public class SupplierController {
private final SupplierService supplierService; private final SupplierService supplierService;

View File

@ -10,6 +10,9 @@ public class SupplierDto {
private int license; private int license;
private List<_Order> orders; private List<_Order> orders;
public SupplierDto(){
}
public SupplierDto(Supplier supplier){ public SupplierDto(Supplier supplier){
this.id = supplier.getId(); this.id = supplier.getId();
this.name = supplier.getName(); this.name = supplier.getName();

View File

@ -0,0 +1,57 @@
package com.example.demo.supply.Supplier;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/supplier")
public class SupplierMvcController {
private final SupplierService supplierService;
public SupplierMvcController(SupplierService supplierService){ this.supplierService = supplierService;}
@GetMapping("/")
public String getProducts(Model model) {
model.addAttribute("suppliers",
supplierService.findAllSuppliers().stream().map(SupplierDto::new).toList());
return "supplier";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editProduct(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("supplierDto", new SupplierDto());
} else {
model.addAttribute("supplierId", id);
model.addAttribute("supplierDto", new SupplierDto(supplierService.findSupplier(id)));
}
return "supplier-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveProduct(@PathVariable(required = false) Long id,
@ModelAttribute @Valid SupplierDto supplierDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "supplier-edit";
}
if (id == null || id <= 0) {
supplierService.addSupplier(supplierDto.getName() , supplierDto.getLicense());
} else {
supplierService.updateSupplier(id, supplierDto.getName(), supplierDto.getLicense());
}
return "redirect:/supplier";
}
@PostMapping("/delete/{id}")
public String deleteProduct(@PathVariable Long id) {
supplierService.deleteSupplier(id);
return "redirect:/supplier";
}
}

View File

@ -1,5 +1,5 @@
spring.main.banner-mode=off spring.main.banner-mode=off
server.port=8080 server.port=8081
spring.datasource.url=jdbc:h2:file:./data spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa spring.datasource.username=sa

View File

@ -0,0 +1,15 @@
.container-padding {
padding: 10px;
}
.margin-bottom {
margin-bottom: 10px;
}
.button-fixed {
min-width: 120px;
}
.button-sm {
padding: 1px;
}

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path d="M448 48V384c-63.09 22.54-82.34 32-119.5 32c-62.82 0-86.6-32-149.3-32C158.6 384 142.6 387.6 128 392.2v-64C142.6 323.6 158.6 320 179.2 320c62.73 0 86.51 32 149.3 32C348.9 352 364.1 349 384 342.7v-208C364.1 141 348.9 144 328.5 144c-62.82 0-86.6-32-149.3-32C128.4 112 104.3 132.6 64 140.7v307.3C64 465.7 49.67 480 32 480S0 465.7 0 448V63.1C0 46.33 14.33 32 31.1 32S64 46.33 64 63.1V76.66C104.3 68.63 128.4 48 179.2 48c62.73 0 86.51 32 149.3 32C365.7 80 384.9 70.54 448 48z"/>
</svg>

After

Width:  |  Height:  |  Size: 727 B

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{main}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>It's works!</div>
<a href="123">ERROR</a>
</div>
</body>
</html>

View File

@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"/>
<title>Поставки</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!-- <link rel="icon" href="/">-->
<!-- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-+0n0xVW2eSR5OomGNYDnhzAbDsOXxcvSN1TPprVMTNDbiYZCxYbOOl7+AMvyTG2x" crossorigin="anonymous">-->
<!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>-->
<script type="text/javascript" src="./webjars/bootstrap"></script>
<link rel="stylesheet" href="./webjars/bootstrap"/>
<link rel="stylesheet" href="./webjars/font-awesome"/>
<link rel="stylesheet" href="../public/favicon.svg"/>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand">
<i class="fa-solid fa-font-awesome"></i>
Поставки
</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav" th:with="activeLink=${#request.requestURI}">
<a class="nav-link" href="/product"
th:classappend="${#strings.equals(activeLink, '/product')} ? 'active' : ''">Продукт</a>
<a class="nav-link" href="/supplier"
th:classappend="${#strings.equals(activeLink, '/supplier')} ? 'active' : ''">Поставщик</a>
<a class="nav-link" href="/swagger-ui/index.html" target="_blank">Документация REST API</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="container container-padding" layout:fragment="content">
</div>
</div>
</body>
<th:block layout:fragment="scripts">
</th:block>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{main}">
<head>
</head>
<body>
<div layout:fragment="content">
<!-- <div th:text="${errors}" class="margin-bottom alert-danger"></div>-->
<form action="#" th:action="@{/product/{id}(id=${id})}" th:object="${productDto}" method="post">
<div class="mb-3">
<label for="name" class="form-label">Название</label>
<input type="text" class="form-control" id="name" th:field="${productDto.name}" required="true">
</div>
<div class="mb-3">
<label for="cost" class="form-label">Цена</label>
<input type="text" class="form-control" id="cost" th:field="${productDto.cost}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/product}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{main}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/product/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Цена</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="product, iterator: ${products}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${product.id}"/>
<td th:text="${product.name}" />
<td th:text="${product.cost}"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/product/edit/{id}(id=${product.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${product.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/product/delete/{id}(id=${product.id})}" method="post">
<button th:id="'remove-' + ${product.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{main}">
<head>
</head>
<body>
<div layout:fragment="content">
<!-- <div th:text="${errors}" class="margin-bottom alert-danger"></div>-->
<form action="#" th:action="@{/product/{id}(id=${id})}" th:object="${productDto}" method="post">
<div class="mb-3">
<label for="name" class="form-label">Название</label>
<input type="text" class="form-control" id="name" th:field="${productDto.name}" required="true">
</div>
<div class="mb-3">
<label for="cost" class="form-label">Лицензия</label>
<input type="text" class="form-control" id="cost" th:field="${productDto.cost}" required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/product}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{main}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-success button-fixed"
th:href="@{/supplier/edit/}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ID</th>
<th scope="col">Название</th>
<th scope="col">Лицензия</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="supplier, iterator: ${suppliers}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${supplier.id}"/>
<td th:text="${supplier.name}" style="width: 60%"/>
<td th:text="${supplier.license}"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/supplier/edit/{id}(id=${supplier.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${supplier.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/supplier/delete/{id}(id=${supplier.id})}" method="post">
<button th:id="'remove-' + ${supplier.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>