Начало таблицы cars
This commit is contained in:
parent
21cb55f3e3
commit
cb8c9949a6
@ -0,0 +1,111 @@
|
|||||||
|
package com.example.autoservice.cars.api;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.modelmapper.ModelMapper;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
import org.springframework.validation.BindingResult;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import com.example.autoservice.cars.model.CarsEntity;
|
||||||
|
import com.example.autoservice.cars.model.CarsGrouped;
|
||||||
|
import com.example.autoservice.cars.service.CarsService;
|
||||||
|
import com.example.autoservice.core.configuration.Constants;
|
||||||
|
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping(CarsController.URL)
|
||||||
|
public class CarsController {
|
||||||
|
public static final String URL = "/cars";
|
||||||
|
private static final String CLIENTS_VIEW = "cars";
|
||||||
|
private static final String CLIENTS_ATTRIBUTE = "cars";
|
||||||
|
private static final String CLIENTS_EDIT_VIEW = "car-edit";
|
||||||
|
private final CarsService carsService;
|
||||||
|
private final ModelMapper modelMapper;
|
||||||
|
|
||||||
|
public CarsController(CarsService carsService, ModelMapper modelMapper) {
|
||||||
|
this.carsService = carsService;
|
||||||
|
this.modelMapper = modelMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CarsDto toDto(CarsEntity entity) {
|
||||||
|
return modelMapper.map(entity, CarsDto.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CarsGroupedDto toGroupedDto(CarsGrouped entity){
|
||||||
|
return modelMapper.map(entity, CarsGroupedDto.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CarsEntity toEntity(CarsDto dto) {
|
||||||
|
return modelMapper.map(dto, CarsEntity.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String getAll(Model model){
|
||||||
|
List<CarsGroupedDto> cars = carsService.getAllCarsWithClients().stream().map(this::toGroupedDto).toList();
|
||||||
|
model.addAttribute("cars",
|
||||||
|
cars);
|
||||||
|
return CLIENTS_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/edit/")
|
||||||
|
public String create(Model model){
|
||||||
|
model.addAttribute(CLIENTS_ATTRIBUTE, new CarsDto());
|
||||||
|
return CLIENTS_EDIT_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/edit/")
|
||||||
|
public String create(
|
||||||
|
@ModelAttribute(name = CLIENTS_ATTRIBUTE) @Valid CarsDto client,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
return CLIENTS_EDIT_VIEW;
|
||||||
|
}
|
||||||
|
carsService.create(toEntity(client));
|
||||||
|
return Constants.REDIRECT_VIEW + URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/edit/{id}")
|
||||||
|
public String update(
|
||||||
|
@PathVariable(name = "id") Long id,
|
||||||
|
Model model) {
|
||||||
|
if (id <= 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
model.addAttribute(CLIENTS_ATTRIBUTE, toDto(carsService.get(id)));
|
||||||
|
return CLIENTS_EDIT_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/edit/{id}")
|
||||||
|
public String update(
|
||||||
|
@PathVariable(name = "id") Long id,
|
||||||
|
@ModelAttribute(name = CLIENTS_ATTRIBUTE) @Valid CarsDto client,
|
||||||
|
BindingResult bindingResult,
|
||||||
|
Model model) {
|
||||||
|
if (bindingResult.hasErrors()) {
|
||||||
|
return CLIENTS_EDIT_VIEW;
|
||||||
|
}
|
||||||
|
if (id <= 0) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
carsService.update(id, toEntity(client));
|
||||||
|
return Constants.REDIRECT_VIEW + URL;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/delete/{id}")
|
||||||
|
public String delete(
|
||||||
|
@PathVariable(name = "id") Long id) {
|
||||||
|
carsService.delete(id);
|
||||||
|
return Constants.REDIRECT_VIEW + URL;
|
||||||
|
}
|
||||||
|
}
|
53
src/main/java/com/example/autoservice/cars/api/CarsDto.java
Normal file
53
src/main/java/com/example/autoservice/cars/api/CarsDto.java
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
package com.example.autoservice.cars.api;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import jakarta.validation.constraints.Min;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
|
||||||
|
public class CarsDto {
|
||||||
|
@JsonProperty(access = JsonProperty.Access.READ_ONLY)
|
||||||
|
private Long id;
|
||||||
|
@NotNull
|
||||||
|
private String mark;
|
||||||
|
@NotNull
|
||||||
|
private String model;
|
||||||
|
@NotNull
|
||||||
|
private String serial_number;
|
||||||
|
@NotNull
|
||||||
|
@Min(1)
|
||||||
|
private Long clientId;
|
||||||
|
|
||||||
|
public String getMark(){
|
||||||
|
return mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMark(String mark){
|
||||||
|
this.mark = mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModel(){
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(String model){
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerial_Number(){
|
||||||
|
return serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerial_Number(String serial_number){
|
||||||
|
this.serial_number = serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getClientId(){
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(Long clientId){
|
||||||
|
this.clientId = clientId;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
package com.example.autoservice.cars.api;
|
||||||
|
|
||||||
|
public class CarsGroupedDto {
|
||||||
|
private String Mark;
|
||||||
|
private String Model;
|
||||||
|
private String SerialNumber;
|
||||||
|
private String FirstName;
|
||||||
|
private String LastName;
|
||||||
|
|
||||||
|
public String getMark(){
|
||||||
|
return Mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMark(String mark){
|
||||||
|
this.Mark = mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModel(){
|
||||||
|
return Model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(String model){
|
||||||
|
this.Model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerial_Number(){
|
||||||
|
return SerialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerial_Number(String serial_number){
|
||||||
|
this.SerialNumber = serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirst_Name(){
|
||||||
|
return FirstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst_Name(String first_name){
|
||||||
|
this.FirstName = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLast_Name(){
|
||||||
|
return LastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLast_Name(String last_name){
|
||||||
|
this.LastName = last_name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
package com.example.autoservice.cars.model;
|
||||||
|
|
||||||
|
import com.example.autoservice.clients.model.ClientsEntity;
|
||||||
|
import com.example.autoservice.core.model.BaseEntity;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
@Entity
|
||||||
|
@Table(name = "cars")
|
||||||
|
public class CarsEntity extends BaseEntity{
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String mark;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String model;
|
||||||
|
@Column(nullable = false)
|
||||||
|
private String serial_number;
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "clientsid", nullable = false)
|
||||||
|
private ClientsEntity client;
|
||||||
|
|
||||||
|
public CarsEntity(){}
|
||||||
|
|
||||||
|
public CarsEntity(String mark, String model, String serial_number, ClientsEntity client){
|
||||||
|
this.mark = mark;
|
||||||
|
this.model = model;
|
||||||
|
this.serial_number = serial_number;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMark(){
|
||||||
|
return mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMark(String mark){
|
||||||
|
this.mark = mark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getModel(){
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setModel(String model){
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSerial_Number(){
|
||||||
|
return serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSerial_Number(String serial_number){
|
||||||
|
this.serial_number = serial_number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClientsEntity getClient(){
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClient(ClientsEntity client){
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package com.example.autoservice.cars.model;
|
||||||
|
|
||||||
|
public interface CarsGrouped {
|
||||||
|
String getMark();
|
||||||
|
String getModel();
|
||||||
|
String getSerialNumber();
|
||||||
|
String getFirstName();
|
||||||
|
String getLastName();
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.example.autoservice.cars.repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.CrudRepository;
|
||||||
|
|
||||||
|
import com.example.autoservice.cars.model.CarsEntity;
|
||||||
|
import com.example.autoservice.cars.model.CarsGrouped;
|
||||||
|
|
||||||
|
public interface CarsRepository extends CrudRepository<CarsEntity, Long> {
|
||||||
|
@Query("select c.mark as mark, c.model as model, c.serial_number as serialNumber, " +
|
||||||
|
"cl.first_name as firstName, cl.last_name as lastName " +
|
||||||
|
"From CarsEntity c " +
|
||||||
|
"join ClientsEntity cl on c.client.id = cl.id")
|
||||||
|
public List<CarsGrouped> findAllCarsWithClients();
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.example.autoservice.cars.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.example.autoservice.cars.model.CarsEntity;
|
||||||
|
import com.example.autoservice.cars.model.CarsGrouped;
|
||||||
|
import com.example.autoservice.cars.repository.CarsRepository;
|
||||||
|
import com.example.autoservice.core.error.NotFoundException;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CarsService {
|
||||||
|
private final CarsRepository repository;
|
||||||
|
|
||||||
|
public CarsService(CarsRepository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public List<CarsEntity> getAll() {
|
||||||
|
return StreamSupport.stream(repository.findAll().spliterator(), false).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public CarsEntity get(Long id) {
|
||||||
|
return repository.findById(id)
|
||||||
|
.orElseThrow(() -> new NotFoundException(CarsEntity.class, id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CarsEntity create(CarsEntity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
throw new IllegalArgumentException("Entity is null");
|
||||||
|
}
|
||||||
|
return repository.save(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CarsEntity update(Long id, CarsEntity entity) {
|
||||||
|
final CarsEntity existsEntity = get(id);
|
||||||
|
existsEntity.setMark(entity.getMark());
|
||||||
|
existsEntity.setModel(entity.getModel());
|
||||||
|
existsEntity.setSerial_Number(entity.getSerial_Number());
|
||||||
|
existsEntity.setClient(entity.getClient());
|
||||||
|
return repository.save(existsEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public CarsEntity delete(Long id) {
|
||||||
|
final CarsEntity existsEntity = get(id);
|
||||||
|
repository.delete(existsEntity);
|
||||||
|
return existsEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public List<CarsGrouped> getAllCarsWithClients(){
|
||||||
|
return repository.findAllCarsWithClients();
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package com.example.autoservice.clients.api;
|
package com.example.autoservice.clients.api;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
46
src/main/resources/templates/car-edit.html
Normal file
46
src/main/resources/templates/car-edit.html
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="ru" xmlns:th="http://www.thymeleaf.org"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||||
|
<head>
|
||||||
|
<title>Редакторовать автомобиль</title>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
|
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
|
||||||
|
<link rel="stylesheet" href="/css/style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main>
|
||||||
|
<form action="#" th:action="@{/cars/edit/{id}(id=${cars.id})}" th:object="${cars}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="id" class="form-label">ID</label>
|
||||||
|
<input type="text" th:value="*{id}" id="id" class="form-control" readonly disabled>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="mark" class="form-label">Имя</label>
|
||||||
|
<input type="text" th:field="*{mark}" id="mark" class="form-control">
|
||||||
|
<div th:if="${#fields.hasErrors('mark')}" th:errors="*{mark}" class="invalid-feedback"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="model" class="form-label">Фамилия</label>
|
||||||
|
<input type="text" th:field="*{model}" id="model" class="form-control">
|
||||||
|
<div th:if="${#fields.hasErrors('model')}" th:errors="*{model}" class="invalid-feedback"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="serial_number" class="form-label">Отчество</label>
|
||||||
|
<input type="text" th:field="*{serial_number}" id="serial_number" class="form-control">
|
||||||
|
<div th:if="${#fields.hasErrors('serial_number')}" th:errors="*{serial_number}" class="invalid-feedback"></div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="clientId" class="form-label">Дата рождения</label>
|
||||||
|
<input type="date" th:field="*{clientId}" id="clientId" class="form-control">
|
||||||
|
<div th:if="${#fields.hasErrors('clientId')}" th:errors="*{clientId}" class="invalid-feedback"></div>
|
||||||
|
<div class="mb-3 d-flex flex-row">
|
||||||
|
<button class="btn btn-primary me-2 button-fixed-width" type="submit">Сохранить</button>
|
||||||
|
<a class="btn btn-secondary button-fixed-width" href="/cars">Отмена</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
51
src/main/resources/templates/cars.html
Normal file
51
src/main/resources/templates/cars.html
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="ru"
|
||||||
|
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{default}">
|
||||||
|
<head>
|
||||||
|
<title>Cars</title>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main layout:fragment="content">
|
||||||
|
<form th:action="@{/cars/edit/}" method="get" class="mb-3">
|
||||||
|
<button type="submit" class="btn btn-primary">Добавить автомобиль</button>
|
||||||
|
</form>
|
||||||
|
<table class="table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope = "col" class="w-10">ID</th>
|
||||||
|
<th scope = "col" class="w-10">Mark</th>
|
||||||
|
<th scope = "col" class="w-10">Model</th>
|
||||||
|
<th scope = "col" class="w-10">Serial Number</th>
|
||||||
|
<th scope = "col" class="w-10">First Name</th>
|
||||||
|
<th scope = "col" class="w-10">Last Name</th>
|
||||||
|
<th scope = "col"></th>
|
||||||
|
<th scope = "col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="car : ${cars}">
|
||||||
|
<th scope="row" th:text="${car.id}"></th>
|
||||||
|
<td th:text="${car.mark}"></td>
|
||||||
|
<td th:text="${car.model}"></td>
|
||||||
|
<td th:text="${car.serial_number}"></td>
|
||||||
|
<td th:text="${car.first_name}"></td>
|
||||||
|
<td th:text="${car.last_name}"></td>
|
||||||
|
<td>
|
||||||
|
<form th:action="@{/cars/edit/{id}(id=${car.id})}" method = "get">
|
||||||
|
<button type="submit" class="btn btn-link button-link">Редактировать</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<form th:action="@{/cars/delete/{id}(id=${car.id})}" method="post">
|
||||||
|
<button type="submit" class="btn btn-link button-link"
|
||||||
|
onclick="return confirm('Вы уверены?')">Удалить</button>
|
||||||
|
</form>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -25,6 +25,9 @@
|
|||||||
<a class="nav-link" href="/clients">
|
<a class="nav-link" href="/clients">
|
||||||
Клиенты
|
Клиенты
|
||||||
</a>
|
</a>
|
||||||
|
<a class="nav-link" href="/cars">
|
||||||
|
Автомобили
|
||||||
|
</a>
|
||||||
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
|
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user