lab3
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,6 +1,7 @@
|
|||||||
HELP.md
|
HELP.md
|
||||||
.gradle
|
.gradle
|
||||||
build/
|
build/
|
||||||
|
database/
|
||||||
!gradle/wrapper/gradle-wrapper.jar
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
!**/src/main/**/build/
|
!**/src/main/**/build/
|
||||||
!**/src/test/**/build/
|
!**/src/test/**/build/
|
||||||
|
|||||||
@@ -27,8 +27,13 @@ dependencies {
|
|||||||
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
|
||||||
|
|
||||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||||
|
|
||||||
|
implementation 'org.hibernate.orm:hibernate-community-dialects'
|
||||||
|
implementation 'org.xerial:sqlite-jdbc:3.46.1.3'
|
||||||
|
|
||||||
compileOnly 'org.projectlombok:lombok'
|
compileOnly 'org.projectlombok:lombok'
|
||||||
annotationProcessor 'org.projectlombok:lombok'
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package ru.lionarius.isdojplab.controller;
|
||||||
|
|
||||||
|
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 ru.lionarius.isdojplab.model.Cart;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/cart")
|
||||||
|
public class CartController {
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public String showCart(Model model) {
|
||||||
|
return "cart";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,24 +1,25 @@
|
|||||||
package ru.lionarius.isdojplab.controller;
|
package ru.lionarius.isdojplab.controller;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import ru.lionarius.isdojplab.model.Product;
|
import ru.lionarius.isdojplab.model.Product;
|
||||||
|
import ru.lionarius.isdojplab.repository.ProductRepository;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class HomeController {
|
public class HomeController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ProductRepository productRepository;
|
||||||
|
|
||||||
@GetMapping("/")
|
@GetMapping("/")
|
||||||
public String home(Model model) {
|
public String home(Model model) {
|
||||||
model.addAttribute("message", "Добро пожаловать в магазин электротоваров!");
|
model.addAttribute("message", "Добро пожаловать в магазин электротоваров!");
|
||||||
|
|
||||||
List<Product> products = new ArrayList<>();
|
List<Product> products = productRepository.findAll();
|
||||||
products.add(new Product("Электрический чайник", 900.0, "Высококачественный чайник с быстрой функцией закипания", "https://example.com/electro1.jpg"));
|
|
||||||
products.add(new Product("Утюг с парогенератором", 1000.0, "Мощный утюг с автоматической подачей пара", "https://example.com/electro2.jpg"));
|
|
||||||
products.add(new Product("Мультиварка", 400.0, "Универсальная мультиварка с множеством режимов приготовления", "https://example.com/electro3.jpg"));
|
|
||||||
|
|
||||||
model.addAttribute("products", products);
|
model.addAttribute("products", products);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package ru.lionarius.isdojplab.controller;
|
package ru.lionarius.isdojplab.controller;
|
||||||
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
@@ -8,9 +9,13 @@ import org.springframework.web.bind.annotation.GetMapping;
|
|||||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import ru.lionarius.isdojplab.model.User;
|
import ru.lionarius.isdojplab.model.User;
|
||||||
|
import ru.lionarius.isdojplab.repository.UserRepository;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class RegisterFormController {
|
public class RegisterFormController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserRepository userRepository;
|
||||||
|
|
||||||
@GetMapping("/register")
|
@GetMapping("/register")
|
||||||
public String showForm(Model model) {
|
public String showForm(Model model) {
|
||||||
@@ -25,6 +30,18 @@ public class RegisterFormController {
|
|||||||
return "register_form";
|
return "register_form";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userRepository.findByEmail(user.getEmail()).isPresent()) {
|
||||||
|
bindingResult.rejectValue("email", "email.already.exists", "Электронная почта уже зарегистрирована");
|
||||||
|
return "register_form";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userRepository.findByName(user.getName()).isPresent()) {
|
||||||
|
bindingResult.rejectValue("name", "name.already.exists", "Имя уже зарегистрировано");
|
||||||
|
return "register_form";
|
||||||
|
}
|
||||||
|
|
||||||
|
userRepository.save(user);
|
||||||
|
|
||||||
model.addAttribute("message", "Пользователь успешно зарегистрирован");
|
model.addAttribute("message", "Пользователь успешно зарегистрирован");
|
||||||
|
|
||||||
return "register_form";
|
return "register_form";
|
||||||
|
|||||||
24
src/main/java/ru/lionarius/isdojplab/model/Cart.java
Normal file
24
src/main/java/ru/lionarius/isdojplab/model/Cart.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package ru.lionarius.isdojplab.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Entity
|
||||||
|
public class Cart {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
private List<CartItem> items;
|
||||||
|
|
||||||
|
private Double totalPrice;
|
||||||
|
}
|
||||||
21
src/main/java/ru/lionarius/isdojplab/model/CartItem.java
Normal file
21
src/main/java/ru/lionarius/isdojplab/model/CartItem.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package ru.lionarius.isdojplab.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Entity
|
||||||
|
public class CartItem {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private Product product;
|
||||||
|
|
||||||
|
private int quantity;
|
||||||
|
}
|
||||||
31
src/main/java/ru/lionarius/isdojplab/model/CartOrder.java
Normal file
31
src/main/java/ru/lionarius/isdojplab/model/CartOrder.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package ru.lionarius.isdojplab.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Entity
|
||||||
|
public class CartOrder {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private String customerName;
|
||||||
|
private String phoneNumber;
|
||||||
|
private String address;
|
||||||
|
private String email;
|
||||||
|
|
||||||
|
@OneToMany(cascade = CascadeType.ALL)
|
||||||
|
private List<CartItem> items;
|
||||||
|
|
||||||
|
private BigDecimal totalPrice;
|
||||||
|
private String paymentMethod;
|
||||||
|
}
|
||||||
@@ -1,16 +1,19 @@
|
|||||||
package ru.lionarius.isdojplab.model;
|
package ru.lionarius.isdojplab.model;
|
||||||
|
|
||||||
import jakarta.validation.constraints.Min;
|
import jakarta.persistence.*;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Entity
|
||||||
public class Product {
|
public class Product {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
private Double price;
|
private Double price;
|
||||||
private String description;
|
private String description;
|
||||||
|
|||||||
@@ -1,17 +1,28 @@
|
|||||||
package ru.lionarius.isdojplab.model;
|
package ru.lionarius.isdojplab.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
import jakarta.validation.constraints.Email;
|
import jakarta.validation.constraints.Email;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Size;
|
import jakarta.validation.constraints.Size;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@Entity
|
||||||
public class User {
|
public class User {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
@NotBlank(message = "Поле не может быть пустым")
|
@NotBlank(message = "Поле не может быть пустым")
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
@NotBlank(message = "Поле не может быть пустым")
|
@NotBlank(message = "Поле не может быть пустым")
|
||||||
@Email(message = "Неверный формат электронной почты")
|
@Email(message = "Неверный формат электронной почты")
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
@NotBlank(message = "Поле не может быть пустым")
|
@NotBlank(message = "Поле не может быть пустым")
|
||||||
@Size(min = 6, message = "Пароль должен состоять не менее 6 символов")
|
@Size(min = 6, message = "Пароль должен состоять не менее 6 символов")
|
||||||
private String password;
|
private String password;
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package ru.lionarius.isdojplab.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import ru.lionarius.isdojplab.model.Product;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface ProductRepository extends JpaRepository<Product, Long> {
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package ru.lionarius.isdojplab.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import ru.lionarius.isdojplab.model.User;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface UserRepository extends JpaRepository<User, Long> {
|
||||||
|
|
||||||
|
Optional<User> findByEmail(String email);
|
||||||
|
Optional<User> findByName(String name);
|
||||||
|
}
|
||||||
@@ -1 +1,7 @@
|
|||||||
spring.application.name=isdojp-lab
|
spring.application.name=isdojp-lab
|
||||||
|
spring.datasource.driver-class-name=org.sqlite.JDBC
|
||||||
|
spring.datasource.url=jdbc:sqlite:./database/data.db
|
||||||
|
spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect
|
||||||
|
spring.jpa.generate-ddl=true
|
||||||
|
spring.jpa.hibernate.ddl-auto=update
|
||||||
|
spring.jpa.show-sql=true
|
||||||
97
src/main/resources/templates/cart.html
Normal file
97
src/main/resources/templates/cart.html
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Корзина и Оформление заказа - Магазин электротоваров</title>
|
||||||
|
<link rel="stylesheet" th:href="@{/css/styles.css}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header>
|
||||||
|
<h1>Магазин электротоваров</h1>
|
||||||
|
<p>Все для вашего дома и офиса</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<!-- Корзина -->
|
||||||
|
<h2>Ваша корзина</h2>
|
||||||
|
<div class="cart">
|
||||||
|
<div th:if="${true}">
|
||||||
|
<p>Ваша корзина пуста.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table th:if="${false}">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Товар</th>
|
||||||
|
<th>Количество</th>
|
||||||
|
<th>Цена</th>
|
||||||
|
<th>Общая стоимость</th>
|
||||||
|
<th>Удалить</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr th:each="item : ${cart.items}">
|
||||||
|
<td th:text="${item.product.name}"></td>
|
||||||
|
<td>
|
||||||
|
<input type="number" th:value="${item.quantity}" min="1" th:attr="data-product-id=${item.product.id}">
|
||||||
|
</td>
|
||||||
|
<td th:text="${item.product.price} + ' $'"></td>
|
||||||
|
<td th:text="${item.totalPrice} + ' $'"></td>
|
||||||
|
<td>
|
||||||
|
<button th:attr="data-product-id=${item.product.id}" class="remove-item-button">Удалить</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="cart-summary" th:if="${false}">
|
||||||
|
<p>Итого к оплате: <span th:text="${cart.totalPrice} + ' $'"></span></p>
|
||||||
|
<a href="#checkout"><button style="padding: 1rem 2rem; font-size: 1.2rem;">Оформить заказ</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Оформление заказа -->
|
||||||
|
<h2 id="checkout">Оформление заказа</h2>
|
||||||
|
<form action="/order/submit" method="post" class="checkout-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="name">ФИО:</label>
|
||||||
|
<input type="text" id="name" name="name" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="phone">Телефон:</label>
|
||||||
|
<input type="tel" id="phone" name="phone" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="address">Адрес доставки:</label>
|
||||||
|
<input type="text" id="address" name="address" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="email">Email:</label>
|
||||||
|
<input type="email" id="email" name="email" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="payment-method">Способ оплаты:</label>
|
||||||
|
<select id="payment-method" name="paymentMethod" required>
|
||||||
|
<option value="card">Банковская карта</option>
|
||||||
|
<option value="cash">Наличные при доставке</option>
|
||||||
|
<option value="online">Онлайн-оплата</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" style="padding: 1rem 2rem; font-size: 1.2rem;">Подтвердить заказ</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>© 2024 Магазин электротоваров. Все права защищены.</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="#" style="margin-top: 2rem; display: inline-block;">
|
<a href="cart" style="margin-top: 2rem; display: inline-block;">
|
||||||
<button style="padding: 1rem 2rem; font-size: 1.2rem;">Перейти в корзину</button>
|
<button style="padding: 1rem 2rem; font-size: 1.2rem;">Перейти в корзину</button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user