Фух, надеюсь, как у *Кое-кого* не попросит доп.задание...

This commit is contained in:
Кашин Максим 2023-05-02 13:57:02 +04:00
parent eeaea74c2f
commit d97e9324a7
33 changed files with 859 additions and 102 deletions

View File

@ -17,7 +17,14 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2:2.1.210'
implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.5'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.hibernate.validator:hibernate-validator'
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'
}
tasks.named('test') {

Binary file not shown.

4
data.trace.db Normal file
View File

@ -0,0 +1,4 @@
2023-05-02 12:16:50 jdbc[13]: exception
org.h2.jdbc.JdbcSQLSyntaxErrorException: Синтаксическая ошибка в выражении SQL "SELECT * FROM BUYER CAR [*]CARS_STORES"
Syntax error in SQL statement "SELECT * FROM BUYER CAR [*]CARS_STORES"; SQL statement:
SELECT * FROM BUYER CAR CARS_STORES [42000-210]

View File

@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class Lab1Application {
public static void main(String[] args) {

View File

@ -9,20 +9,15 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addCorsMappings(CorsRegistry registry){
registry.addMapping("/**").allowedMethods("*");
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
ViewControllerRegistration registration = registry.addViewController("/notFound");
registration.setViewName("forward:/index.html");
registration.setStatusCode(HttpStatus.OK);
WebMvcConfigurer.super.addViewControllers(registry);
registry.addViewController("rest-test");
}
// @Bean
// public WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> containerCustomizer() {
// return container -> {
// container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notFound"));
// };
// }
}

View File

@ -7,7 +7,7 @@ import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/buyer")
@RequestMapping("(WebConfiguration.REST_API + /buyer")
public class BuyerController {
private final BuyerService buyerService;
public BuyerController(BuyerService buyerService){

View File

@ -1,10 +1,15 @@
package ru.ulsru.is.lab1.lab3.controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulsru.is.lab1.lab3.model.Buyer;
import javax.validation.constraints.NotBlank;
public class BuyerDTO {
private long id;
@NotBlank(message = "buyerFirstName can't be null or empty")
private String buyerFirstName;
@NotBlank(message = "buyerSecondName can't be null or empty")
private String buyerSecondName;
public BuyerDTO(Buyer buyer){
this.id =buyer.getId();
@ -13,13 +18,20 @@ public class BuyerDTO {
}
public BuyerDTO(){
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getId() {
return id;
}
public String getBuyerFirstName(){
return buyerFirstName;
}
public void setBuyerFirstName(String buyerFirstName){
this.buyerFirstName = buyerFirstName;
}
public String getBuyerSecondName(){
return buyerSecondName;
}
public void setBuyerSecondName(String buyerSecondName){
this.buyerSecondName = buyerSecondName;
}
}

View File

@ -0,0 +1,59 @@
package ru.ulsru.is.lab1.lab3.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulsru.is.lab1.lab3.service.BuyerService;
import javax.validation.Valid;
@Controller
@RequestMapping("/buyer")
public class BuyerMVCController {
private final BuyerService buyerService;
public BuyerMVCController(BuyerService buyerService){
this.buyerService = buyerService;
}
@GetMapping
public String getBuyers(Model model){
model.addAttribute("buyers",
buyerService.findAllBuyers().stream()
.map(BuyerDTO::new)
.toList());
return "buyer";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editBuyer(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("BuyerDTO", new BuyerDTO());
} else {
model.addAttribute("buyerId", id);
model.addAttribute("BuyerDTO", new BuyerDTO(buyerService.findBuyer(id)));
}
return "buyer-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveBuyer(@PathVariable(required = false) Long id,
@ModelAttribute @Valid BuyerDTO buyerDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "buyer-edit";
}
if (id == null || id <= 0) {
buyerService.addBuyer(buyerDTO);
} else {
buyerService.updateBuyer(id, buyerDTO);
}
return "redirect:/buyer";
}
@PostMapping("/delete/{id}")
public String deleteBuyer(@PathVariable Long id) {
buyerService.deleteBuyer(id);
return "redirect:/buyer";
}
}

View File

@ -7,7 +7,7 @@ import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/car")
@RequestMapping("WebConfiguration.REST_API + /car")
public class CarController {
private final CarService carService;
public CarController(CarService carService){

View File

@ -1,11 +1,14 @@
package ru.ulsru.is.lab1.lab3.controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulsru.is.lab1.lab3.model.Car;
import javax.validation.constraints.NotBlank;
import java.util.List;
public class CarDTO {
private long id;
@NotBlank(message = "carName can't be null or empty")
private String carName;
private List<BuyerDTO> buyerDTOList;
private List<StoreDTO> storeDTOList;
@ -23,6 +26,7 @@ public class CarDTO {
.toList();
}
public CarDTO(){}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getId() {
return id;
}
@ -32,6 +36,19 @@ public class CarDTO {
public List<BuyerDTO> getBuyerDTOList(){
return buyerDTOList;
}
public void setCarName(String carName) {
this.carName = carName;
}
public void setBuyerDTOList(List<BuyerDTO> buyerDTOList) {
this.buyerDTOList = buyerDTOList;
}
public void setStoreDTOList(List<StoreDTO> storeDTOList) {
this.storeDTOList = storeDTOList;
}
public List<StoreDTO> getStoreDTOList(){
return storeDTOList;
}

View File

@ -0,0 +1,119 @@
package ru.ulsru.is.lab1.lab3.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulsru.is.lab1.lab3.service.StoreService;
import ru.ulsru.is.lab1.lab3.service.BuyerService;
import ru.ulsru.is.lab1.lab3.service.CarService;
import javax.validation.Valid;
import java.util.List;
@Controller
@RequestMapping("/car")
public class CarMVCController {
private final CarService carService;
private final BuyerService buyerService;
private final StoreService storeService;
public CarMVCController(CarService carService, BuyerService buyerService, StoreService storeService){
this.carService = carService;
this.buyerService = buyerService;
this.storeService = storeService;
}
@GetMapping
public String getCars(Model model){
model.addAttribute("cars",
carService.findAllCars().stream()
.map(CarDTO::new)
.toList());
return "car";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editCar(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
List<BuyerDTO> buyers = buyerService.findAllBuyers().stream()
.map(BuyerDTO::new).toList();
List<StoreDTO> stores = storeService.findAllStores().stream()
.map(StoreDTO::new).toList();
model.addAttribute("CarDTO", new CarDTO());
model.addAttribute("buyers", buyers);
model.addAttribute("stores", stores);
return "car-create";
} else {
String name = carService.findCar(id).getCarName();
List<BuyerDTO> buyers = buyerService.findAllBuyers().stream()
.map(BuyerDTO::new).toList();
List<BuyerDTO> carBuyers = carService
.findCar(id)
.getBuyers()
.stream()
.map(BuyerDTO::new)
.toList();
List<StoreDTO> stores = storeService.findAllStores().stream()
.map(StoreDTO::new).toList();
List<StoreDTO> carStores = carService
.findCar(id)
.getStores()
.stream()
.map(StoreDTO::new)
.toList();
model.addAttribute("name", name);
model.addAttribute("carId", id);
model.addAttribute("carBuyers", carBuyers);
model.addAttribute("buyers", buyers);
model.addAttribute("carStores", carStores);
model.addAttribute("stores", stores);
model.addAttribute("CarDTO", new CarDTO(carService.findCar(id)));
}
return "car-set";
}
@PostMapping(value = {"/"})
public String saveCar(@ModelAttribute @Valid CarDTO carDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "car-create";
}
carService.addCar(carDTO);
// } else {
// carService.updateCar(id, carDTO);
// }
return "redirect:/car";
}
@PostMapping(value = {"/{id}"})
public String editCar(@PathVariable Long id,
@RequestParam("PW") String PW,
@RequestParam("wpName") String name,
@RequestParam(value="idPW", required = false) Long idPW,
@RequestParam(value = "delete", required = false) boolean del,
Model model) {
if(PW.equals("N")){
carService.findCar(id).setCarName(name);
carService.updateCar(id, new CarDTO(carService.findCar(id)));
}
if (PW.equals("W")){
if (del == true) {
carService.deleteBuyer(id, idPW);
} else {
carService.addBuyer(id, idPW);
}
}
else if(PW.equals("P")){
if (del == true) {
carService.deleteStore(id, idPW);
} else {
carService.addStore(id, idPW);
}
}
return "redirect:/car/edit/" + id;
}
@PostMapping("/delete/{id}")
public String deleteCar(@PathVariable Long id) {
carService.deleteCar(id);
return "redirect:/car";
}
}

View File

@ -7,7 +7,7 @@ import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/store")
@RequestMapping("WebConfiguration.REST_API + /store")
public class StoreController {
private final StoreService storeService;
public StoreController(StoreService storeService){

View File

@ -1,11 +1,14 @@
package ru.ulsru.is.lab1.lab3.controller;
import com.fasterxml.jackson.annotation.JsonProperty;
import ru.ulsru.is.lab1.lab3.model.Store;
import javax.validation.constraints.NotBlank;
import java.util.List;
public class StoreDTO {
private long id;
@NotBlank(message = "storeName can't be null or empty")
private String storeName;
private List<CarDTO> carDTOList;
public StoreDTO(Store store){
@ -19,13 +22,16 @@ public class StoreDTO {
}
public StoreDTO() {
}
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
public long getId() {
return id;
}
public String getStoreName() {
return storeName;
}
public void setStoreName(String storeName){
this.storeName = storeName;
}
public List<CarDTO> getCarDTOList(){
return carDTOList;

View File

@ -0,0 +1,68 @@
package ru.ulsru.is.lab1.lab3.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import ru.ulsru.is.lab1.lab3.service.StoreService;
import javax.validation.Valid;
@Controller
@RequestMapping("/store")
public class StoreMVCController {
private final StoreService storeService;
public StoreMVCController(StoreService storeService){
this.storeService = storeService;
}
@GetMapping
public String getStores(Model model){
model.addAttribute("stores",
storeService.findAllStores().stream()
.map(StoreDTO::new)
.toList());
return "store";
}
@GetMapping("/info/{id}")
public String findBuyersOnWorkplace(@PathVariable(required = false) Long id, Model model){
model.addAttribute("cathegory", "Кто производит " + storeService.findStore(id).getStoreName());
model.addAttribute("buyers", storeService.findAllBuyersProducedStore(id)
.stream()
.map(BuyerDTO::new)
.toList());
model.addAttribute("page", "store");
return "buyer-info";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editStore(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("StoreDTO", new StoreDTO());
} else {
model.addAttribute("storeId", id);
model.addAttribute("StoreDTO", new StoreDTO(storeService.findStore(id)));
}
return "store-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveStore(@PathVariable(required = false) Long id,
@ModelAttribute @Valid StoreDTO storeDTO,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "store-edit";
}
if (id == null || id <= 0) {
storeService.addStore(storeDTO);
} else {
storeService.updateStore(id, storeDTO);
}
return "redirect:/store";
}
@PostMapping("/delete/{id}")
public String deleteStore(@PathVariable Long id) {
storeService.deleteStore(id);
return "redirect:/store";
}
}

View File

@ -6,6 +6,7 @@ import ru.ulsru.is.lab1.lab3.Respository.IBuyerRespository;
import ru.ulsru.is.lab1.lab3.controller.BuyerDTO;
import ru.ulsru.is.lab1.lab3.controller.CarDTO;
import ru.ulsru.is.lab1.lab3.model.Buyer;
import ru.ulsru.is.lab1.util.validation.ValidatorUtil;
import java.util.List;
import java.util.Optional;
@ -13,12 +14,15 @@ import java.util.Optional;
@Service
public class BuyerService {
private final IBuyerRespository buyerRespository;
public BuyerService(IBuyerRespository buyerRespositroy){
private final ValidatorUtil validatorUtil;
public BuyerService(IBuyerRespository buyerRespositroy, ValidatorUtil validatorUtil){
this.buyerRespository = buyerRespositroy;
this.validatorUtil = validatorUtil;
}
@Transactional
public Buyer addBuyer(BuyerDTO buyerDTO) {
final Buyer buyer = new Buyer(buyerDTO.getBuyerFirstName(), buyerDTO.getBuyerSecondName());
validatorUtil.validate(buyer);
buyerRespository.save(buyer);
return buyer;
}
@ -29,6 +33,9 @@ public class BuyerService {
}
@Transactional(readOnly = true)
public List<Buyer> findAllBuyerByid(CarDTO carDTO) {
if(carDTO.getBuyerDTOList() == null){
return null;
}
return buyerRespository
.findAllById(carDTO
.getBuyerDTOList()
@ -48,6 +55,7 @@ public class BuyerService {
final Buyer currentBuyer = findBuyer(id);
currentBuyer.setBuyerFirstName(buyer.getBuyerFirstName());
currentBuyer.setBuyerSecondName(buyer.getBuyerSecondName());
validatorUtil.validate(currentBuyer);
buyerRespository.save(currentBuyer);
return currentBuyer;
}

View File

@ -37,15 +37,28 @@ public class CarService {
return car;
}
@Transactional
public Car addBuyer(CarDTO carDTO, List<Buyer> buyers){
final Car currentCar = findCar(carDTO.getId());
currentCar.setBuyers(buyers);
public Car addBuyer(Long id, Long idW){
final Car currentCar = findCar(id);
currentCar.addBuyer(buyerService.findBuyer(idW));
return currentCar;
}
@Transactional
public Car addStore(CarDTO carDTO, List<Store> stores){
final Car currentCar = findCar(carDTO.getId());
currentCar.setStores(stores);
public Car deleteBuyer(Long id, Long idW){
final Car currentCar = findCar(id);
currentCar.removeBuyer(buyerService.findBuyer(idW));
return currentCar;
}
@Transactional
public Car addStore(Long id, Long idP) {
final Car currentCar = findCar(id);
currentCar.addStore(storeService.findStore(idP));
return currentCar;
}
@Transactional
public Car deleteStore(Long id, Long idP){
final Car currentCar = findCar(id);
currentCar.removeStore(storeService.findStore(idP));
return currentCar;
}
@Transactional(readOnly = true)

View File

@ -36,6 +36,9 @@ public class StoreService {
}
@Transactional(readOnly = true)
public List<Store> findAllStoresById(CarDTO carDTO) {
if(carDTO.getStoreDTOList() == null){
return null;
}
return storeRespository
.findAllById(carDTO
.getStoreDTOList()

View File

@ -1,41 +0,0 @@
//package ru.ulsru.is.lab1.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 ru.ulsru.is.lab1.lab3.service.ProductNotFoundException;
//import ru.ulsru.is.lab1.lab3.service.WorkerNotFoundException;
//import ru.ulsru.is.lab1.lab3.service.WorkplaceNotFoundException;
//import ru.ulsru.is.lab1.util.validation.ValidationException;
//import java.util.stream.Collectors;
//
// @ControllerAdvice
// public class AdviceController {
// @ExceptionHandler({
// WorkerNotFoundException.class,
// ProductNotFoundException.class,
// WorkplaceNotFoundException.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);
// }
// }

View File

@ -1,9 +1,9 @@
//package ru.ulsru.is.lab1.util.validation;
//
//import java.util.Set;
//
//public class ValidationException extends RuntimeException {
// public ValidationException(Set<String> errors) {
// super(String.join("\n", errors));
// }
//}
package ru.ulsru.is.lab1.util.validation;
import java.util.Set;
public class ValidationException extends RuntimeException {
public <T> ValidationException(Set<String> errors) {
super(String.join("\n", errors));
}
}

View File

@ -1,30 +1,30 @@
//package ru.ulsru.is.lab1.util.validation;
//
//import org.springframework.stereotype.Component;
//
//import javax.validation.ConstraintViolation;
//import javax.validation.Validation;
//import javax.validation.Validator;
//import javax.validation.ValidatorFactory;
//import java.util.Set;
//import java.util.stream.Collectors;
//
//@Component
//public class ValidatorUtil {
// private final Validator validator;
//
// public ValidatorUtil() {
// try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
// this.validator = factory.getValidator();
// }
// }
//
// public <T> void validate(T object) {
// final Set<ConstraintViolation<T>> errors = validator.validate(object);
// if (!errors.isEmpty()) {
// throw new ValidationException(errors.stream()
// .map(ConstraintViolation::getMessage)
// .collect(Collectors.toSet()));
// }
// }
//}
package ru.ulsru.is.lab1.util.validation;
import org.springframework.stereotype.Component;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.Set;
import java.util.stream.Collectors;
@Component
public class ValidatorUtil {
private final Validator validator;
public ValidatorUtil() {
try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
this.validator = factory.getValidator();
}
}
public <T> void validate(T object) {
final Set<ConstraintViolation<T>> errors = validator.validate(object);
if (!errors.isEmpty()) {
throw new ValidationException(errors.stream()
.map(ConstraintViolation::getMessage)
.collect(Collectors.toSet()));
}
}
}

View File

@ -1,6 +1,6 @@
spring.main.banner-mode=off
server.port=8080
server.tomcat.relaxed-query-chars=|,{,},[,]
#server.tomcat.relaxed-query-chars=|,{,},[,]
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa

View File

@ -0,0 +1,12 @@
.footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #f5f5f5;
color: #333;
text-align: center;
padding: 10px;
}

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ultraq.net.nz/thymeleaf/layout ">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/buyer/{id}(id=${id})}" th:object="${BuyerDTO}" method="post">
<div class="mb-3">
<label for="buyerFirstName" class="form-label">Имя</label>
<input type="text" class="form-control" id="buyerFirstName" th:field="${BuyerDTO.buyerFirstName}"
required="true">
</div>
<div class="mb-3">
<label for="buyerSecondName" class="form-label">Фамилия</label>
<input type="text" class="form-control" id="buyerSecondName" th:field="${BuyerDTO.buyerSecondName}"
required="true">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-outline-dark text-center button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/buyer}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></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>
</tr>
</thead>
<tbody>
<tr th:each="buyer, iterator: ${buyers}">
<th scope="row" th:text="${iterator.index} + 1"></th>
<td th:text="${buyer.id}"></td>
<td th:text="${buyer.buyerFirstName}" style="width: 40%"></td>
<td th:text="${buyer.buyerSecondName}" style="width: 40%"></td>
</tr>
</tbody>
</table>
</div>
<a class="btn btn-secondary button-fixed d-flex justify-content-center mt-3" th:href="@{/} + ${page}">
Назад
</a>
</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="~{default}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ultraq.net.nz/thymeleaf/layout " xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/buyer/edit/}">
Добавить
</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>
</tr>
</thead>
<tbody>
<tr th:each="buyer, iterator: ${buyers}">
<th scope="row" th:text="${iterator.index} + 1"></th>
<td th:text="${buyer.id}"></td>
<td th:text="${buyer.buyerFirstName}" style="width: 40%"></td>
<td th:text="${buyer.buyerSecondName}" style="width: 40%"></td>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/buyer/edit/{id}(id=${buyer.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${buyer.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/buyer/delete/{id}(id=${buyer.id})}" method="post">
<button th:id="'remove-' + ${buyer.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/car/{id}(id=${id})}" th:object="${CarDTO}" method="post">
<div class="mb-3">
<label for="carName" class="form-label">Название</label>
<input type="text" class="form-control" id="carName" th:field="${CarDTO.carName}" 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="@{/car}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="en" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ultraq.net.nz/thymeleaf/layout " xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content" class="mw-100">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/car/{id}(id=${id})}" method="post" class="mb-3">
<div class="d-flex justify-content-center">
<input name="PW" type="hidden" th:value="N" />
<label for="wpName" class="form-label mt-2">Название</label>
<input type="text" class="d-flex justify-content-center form-control" id="wpName" style="width: 30vw; margin-left: 2vw;" th:value="${name}" name="wpName"/>
<div style="margin-left: 2vw;">
<button type="submit" class="btn btn-outline-dark text-center button-fixed">
<span>Обновить</span>
</button>
</div>
<div style="margin-left: 2vw;">
<a class="btn btn-outline-dark text-center button-fixed" th:href="@{/car}">
Назад
</a>
</div>
</div>
</form>
<div class="d-flex container-fluid ">
<div style="width: 45vw; margin-right: 2vw" class="container-fluid">
<form action="#" th:action="@{/car/{id}(id=${id})}" method="post" >
<input name="wpName" type="hidden" th:value="${name}" />
<input name="PW" type="hidden" th:value="W" />
<div class="mb-3">
<label for="idW" class="form-label">Покупатель</label>
<select class="form-select" id = "idW" th:name="idPW">
<option th:each="value: ${buyers}"
th:value="${value.id}"
th:text="${value.buyerFirstName} + ' ' + ${value.buyerSecondName}">
</option>
</select>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-outline-dark text-center button-fixed">
<span>Добавить</span>
</button>
</div>
</form>
<table class="table" id="tbl-items">
<thead>
<tr>
<th scope="col">id</th>
<th scope="col">Имя</th>
<th scope="col">Фамилия</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="carBuyer, iterator: ${carBuyers}">
<td th:text="${iterator.index} + 1"></td>
<td th:text="${carBuyer.buyerFirstName}"></td>
<td th:text="${carBuyer.buyerSecondName}"></td>
<td>
<div>
<a type="button" class="btn btn-outline-dark text-center button-fixed"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${carBuyer.id}').click()|">
<i class="fa fa-trash"></i>
</a>
</div>
<form th:action="@{'/car/' + ${id} + '?PW=W&wpName='+ ${name} +'&idPW=' + ${carBuyer.id} + '&delete=true'}" method="post">
<button th:id="'remove-' + ${carBuyer.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
<div style="width: 45vw; margin-left: 2vw" class="container-fluid">
<form action="#" th:action="@{/car/{id}(id=${id})}" method="post" class="mb-3">
<input name="wpName" type="hidden" th:value="${name}" />
<input type="hidden" th:value="P" name="PW"/>
<div class="mb-3">
<label for="idP" class="form-label">Магазин</label>
<select class="form-select" id = "idP" th:name="idPW">
<option th:each="store, iterator: ${stores}"
th:value="${store.id}"
th:text="${store.storeName}">
</option>
</select>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-outline-dark text-center button-fixed">
<span>Добавить</span>
</button>
</div>
</form>
<table class="table" id="tbl-items">
<thead>
<tr>
<th scope="col">id</th>
<th scope="col">Название</th>
<th scope="col">Цена</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="carStore, iterator: ${carStores}">
<td th:text="${iterator.index} + 1"></td>
<td th:text="${carStore.storeName}"></td>
<td>
<div>
<a type="button" class="btn btn-outline-dark text-center button-fixed"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${carStore.id}').click()|">
<i class="fa fa-trash"></i>
</a>
</div>
<form th:action="@{'/car/' + ${id} + '?PW=P&wpName='+ ${name} + '&idPW=' + ${carStore.id} + '&delete=true'}" method="post">
<button class = "btn btn-outline-dark text-center button-fixed" th:id="'remove-' + ${carStore.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/car/edit/}">
Добавить
</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>
</tr>
</thead>
<tbody>
<tr th:each="car, iterator: ${cars}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${car.id}"/>
<td th:text="${car.carName}" style="width: 60%"/>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/car/edit/{id}(id=${car.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${car.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/car/delete/{id}(id=${car.id})}" method="post">
<button th:id="'remove-' + ${car.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,38 @@
<!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>Кашин Максим ПИбд-22</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
<link rel="stylesheet" href="../static/css/style.css" th:href="@{/css/style.css}"/>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav" th:with="activeLink=${#request.requestURI}">
<a class="nav-link" href="/store"
th:classappend="${#strings.equals(activeLink, '/store')} ? 'active' : ''">Магазины</a>
<a class="nav-link" href="/buyer"
th:classappend="${#strings.equals(activeLink, '/buyer')} ? 'active' : ''">Покупатели</a>
<a class="nav-link" href="/car"
th:classappend="${#strings.equals(activeLink, '/car')} ? 'active' : ''">Машины</a>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="container container-padding" layout:fragment="content">
</div>
</div>
<footer class = "footer">
Кашин Максим ПИбд-22
</footer>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
</body>
</html>

View File

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

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}" xmlns:th="http://www.w3.org/1999/xhtml">
<head>
</head>
<body>
<div layout:fragment="content">
<div>
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/store/edit/}">
Добавить
</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>
</tr>
</thead>
<tbody>
<tr th:each="store, iterator: ${stores}">
<th scope="row" th:text="${iterator.index} + 1"/>
<td th:text="${store.id}"/>
<td th:text="${store.storeName}" style="width: 40%"></td>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/store/info/{id}(id=${store.id})}">
<i class="fa fa-info" aria-hidden="true"></i> Инфо
</a>
<a class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:href="@{/store/edit/{id}(id=${store.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-outline-dark text-center d-flex justify-content-md-center mx-5"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${store.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/store/delete/{id}(id=${store.id})}" method="post">
<button th:id="'remove-' + ${store.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>