diff --git a/data/images/product/e495ff3eb9c55bd0bcdde0f468b679f4.jpg b/data/images/product/e495ff3eb9c55bd0bcdde0f468b679f4.jpg new file mode 100644 index 0000000..e455463 Binary files /dev/null and b/data/images/product/e495ff3eb9c55bd0bcdde0f468b679f4.jpg differ diff --git "a/data/images/product/\320\241\320\275\320\270\320\274\320\276\320\272 \321\215\320\272\321\200\320\260\320\275\320\260 2021-08-25 141911.png" "b/data/images/product/\320\241\320\275\320\270\320\274\320\276\320\272 \321\215\320\272\321\200\320\260\320\275\320\260 2021-08-25 141911.png" deleted file mode 100644 index bda794b..0000000 Binary files "a/data/images/product/\320\241\320\275\320\270\320\274\320\276\320\272 \321\215\320\272\321\200\320\260\320\275\320\260 2021-08-25 141911.png" and /dev/null differ diff --git a/docker/docker-compose.yml b/docker/nikitin/docker-compose.yml similarity index 100% rename from docker/docker-compose.yml rename to docker/nikitin/docker-compose.yml diff --git a/pom.xml b/pom.xml index 022b565..e5be462 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,12 @@ 11 + + com.vladmihalcea + hibernate-types-52 + 2.12.1 + + org.springframework.boot spring-boot-starter-web @@ -52,12 +58,6 @@ 2.5.3 - - - - - - org.flywaydb flyway-core @@ -77,6 +77,23 @@ commons-collections4 4.4 + + + org.springframework.boot + spring-boot-starter-security + + + org.thymeleaf.extras + thymeleaf-extras-springsecurity5 + 3.0.4.RELEASE + + + + org.modelmapper + modelmapper + 2.4.4 + + diff --git a/src/main/java/com/example/springmvc/controller/ProductController.java b/src/main/java/com/example/springmvc/controller/ProductController.java deleted file mode 100644 index 28c1e0f..0000000 --- a/src/main/java/com/example/springmvc/controller/ProductController.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.example.springmvc.controller; - - -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.search.ProductSearchCondition; -import com.example.springmvc.domain.dto.ProductDto; -import com.example.springmvc.service.CategoryService; -import com.example.springmvc.service.ProductService; -import lombok.AllArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; -import org.springframework.web.servlet.view.RedirectView; - -import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; - -import static com.example.springmvc.domain.constans.ConstanceName.*; - -@AllArgsConstructor -@Controller -@RequestMapping(PRODUCT) -public class ProductController { - - private ProductService productService; - private CategoryService categoryService; - - - @GetMapping(LIST) - public String getListProducts(ProductSearchCondition searchCondition,Model model) { -// List products = productService.findProducts(); - Page page = productService.findAllBySearchConditional(searchCondition); - - - int totalPages = page.getTotalPages(); - - if (totalPages > 0) { - List pageNumbers = IntStream.rangeClosed(1, totalPages) - .boxed() - .collect(Collectors.toList()); - model.addAttribute("pageNumbers", pageNumbers); - } - model.addAttribute("pageNum", searchCondition.getPageNum()); - model.addAttribute("page", page); - model.addAttribute("pageSize", searchCondition.getPageSize()); -// model.addAttribute("page", page); - return "product/list"; - } - - @GetMapping(FORM) - public String getProductForm(Model model, @RequestParam(required = false) Integer id) { - List categories = categoryService.findCategory(); - model.addAttribute("categories", categories); - if (id != null) { - ProductDto productDtoById = productService.findProductDtoById(id); - model.addAttribute("product", productDtoById); - } else { - model.addAttribute("product", new ProductDto()); - } - return "product/form"; - } - - @PostMapping(FORM) - public RedirectView saveProduct(ProductDto product, - @RequestParam(required = false) MultipartFile image) { - productService.saveProductAndImage(product, image); - return new RedirectView("/product/list"); - } - - @ExceptionHandler(Exception.class) - public String handleError(HttpServletRequest req, Exception ex) { - System.err.println("Request: " + req.getRequestURL() + " raised " + ex); - return "error"; - } - - @GetMapping(DELETE) - public String deleteProductById(@RequestParam Integer id, Model model) { - productService.deleteProductById(id); - model.addAttribute("products", productService.findProducts()); - return "product/list"; - } - - @GetMapping(FILTER) - public String filterProductsByTitleAndByMaxAndMinPrice(@RequestParam(required = false) String title, - @RequestParam(required = false) Integer minPrice, - @RequestParam(required = false) Integer maxPrice, Model model) { - List products = productService.findProductsByTitleAndByMaxAndMinPrice(title, minPrice, maxPrice); - model.addAttribute("products", products); - return ("product/list"); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/controller/rest/CategoryController.java b/src/main/java/com/example/springmvc/controller/rest/CategoryController.java deleted file mode 100644 index c60f914..0000000 --- a/src/main/java/com/example/springmvc/controller/rest/CategoryController.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.example.springmvc.controller.rest; - - -import com.example.springmvc.domain.Category; -import com.example.springmvc.service.CategoryService; -import lombok.AllArgsConstructor; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; - -import java.util.List; - -import static com.example.springmvc.domain.constans.ConstanceName.*; -@AllArgsConstructor -@RequestMapping(API_V1+CATEGORY) -@RestController("restCategoryController") -public class CategoryController { - CategoryService categoryService; - - @GetMapping - public List getCategories() { - return categoryService.findCategory(); - } - - @GetMapping("/{id}") - public Category getCategoryById(@PathVariable Integer id) { - return categoryService.findCategoryById(id).get(); - } - - @PostMapping - public int addCategory(@RequestBody String title) { - categoryService.addCategory(title); - return HttpStatus.OK.value(); - } - - @PutMapping("/{id}") - public int updateCategory(@PathVariable Integer id, @RequestBody String title) { - categoryService.updateCategory(id, title); - return HttpStatus.OK.value(); - } - - @DeleteMapping("/{id}") - public int deleteCategory(@PathVariable Integer id) { - categoryService.deleteCategory(id); - return HttpStatus.OK.value(); - } -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/controller/rest/ProductController.java b/src/main/java/com/example/springmvc/controller/rest/ProductController.java deleted file mode 100644 index 9874163..0000000 --- a/src/main/java/com/example/springmvc/controller/rest/ProductController.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.example.springmvc.controller.rest; - -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.search.ProductSearchCondition; -import com.example.springmvc.domain.dto.ProductDto; -import com.example.springmvc.service.ProductService; -import lombok.AllArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.*; - -import static com.example.springmvc.domain.constans.ConstanceName.*; - -@AllArgsConstructor -@RequestMapping(API_V1+PRODUCT) -@RestController("restProductController") -public class ProductController { - - private ProductService productService; - - @GetMapping("/{id}") - private ProductDto getProductById(@PathVariable Integer id) { - return productService.findProductDtoById(id); - } -// -// @GetMapping -// public List getAllProducts() { -// return productService.findProducts(); -// } - - @PostMapping - public Page getAllProducts(@RequestBody ProductSearchCondition searchCondition) { - return productService.findAllBySearchConditional(searchCondition); - } - - - @PutMapping - public Product updateProduct(@RequestBody Product product) { - return productService.saveProduct(product); - } - - @PostMapping("/add") - public Product addProduct(@RequestBody Product product) { - return productService.saveProduct(product); - } - - @DeleteMapping("/{id}") - public int deleteProduct(@PathVariable Integer id) { - productService.deleteProductById(id); - return HttpStatus.OK.value(); - } -} diff --git a/src/main/java/com/example/springmvc/converter/ConverterCategory.java b/src/main/java/com/example/springmvc/converter/ConverterCategory.java deleted file mode 100644 index 451648f..0000000 --- a/src/main/java/com/example/springmvc/converter/ConverterCategory.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.springmvc.converter; - -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.dto.CategoryDto; -import com.example.springmvc.service.ProductService; - -import java.util.Set; - -public class ConverterCategory { - private static ProductService productService; - - public static CategoryDto convert(Category category){ - return CategoryDto.builder().id(category.getId()) - .title(category.getTitle()) - .productsDto(productService.findProductsDtoByCategoryId(category.getId())) - .build(); - - } -} diff --git a/src/main/java/com/example/springmvc/converter/ProductConverter.java b/src/main/java/com/example/springmvc/converter/ProductConverter.java deleted file mode 100644 index 440416b..0000000 --- a/src/main/java/com/example/springmvc/converter/ProductConverter.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.example.springmvc.converter; - -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.dto.ProductDto; -import com.example.springmvc.service.CategoryService; - -public class ProductConverter { - private static CategoryService categoryService; - public static ProductDto productConvertToDtoProduct(Product product) { - return ProductDto.builder().id(product.getId()) - .title(product.getTitle()) - .price(product.getPrice()) - .categories(product.getCategories()).build(); - } - - public static Product dtoProductConvertToProduct(ProductDto productDto, Product product) { - product.setTitle(productDto.getTitle()); - product.setPrice(productDto.getPrice()); - product.setCategories(productDto.getCategories()); - return product; - } -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/domain/dto/ProductDto.java b/src/main/java/com/example/springmvc/domain/dto/ProductDto.java deleted file mode 100644 index e6cbff1..0000000 --- a/src/main/java/com/example/springmvc/domain/dto/ProductDto.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.example.springmvc.domain.dto; - -import com.example.springmvc.domain.Category; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Set; - -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class ProductDto { - private Integer id; - private String title; - private Integer price; - private Set categories; -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/domain/search/ProductSearchCondition.java b/src/main/java/com/example/springmvc/domain/search/ProductSearchCondition.java deleted file mode 100644 index 6ac6f12..0000000 --- a/src/main/java/com/example/springmvc/domain/search/ProductSearchCondition.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.example.springmvc.domain.search; - -import lombok.Data; -import org.springframework.data.domain.Sort; - -@Data -public class ProductSearchCondition { - private Sort.Direction sortDirection=Sort.Direction.ASC; - private String sortField="title"; - - private int pageNum; - private Integer pageSize=20; - -// private List pageNumbers = Collections.singletonList(1); -// -// private Page page; - -// private String titleFilter; -} diff --git a/src/main/java/com/example/springmvc/component/ShoppingCart.java b/src/main/java/com/example/springmvc/mvcLayer/component/ShoppingCart.java similarity index 85% rename from src/main/java/com/example/springmvc/component/ShoppingCart.java rename to src/main/java/com/example/springmvc/mvcLayer/component/ShoppingCart.java index b438ed6..27d5ed8 100644 --- a/src/main/java/com/example/springmvc/component/ShoppingCart.java +++ b/src/main/java/com/example/springmvc/mvcLayer/component/ShoppingCart.java @@ -1,14 +1,13 @@ -package com.example.springmvc.component; +package com.example.springmvc.mvcLayer.component; -import com.example.springmvc.domain.CartItem; -import lombok.Getter; +import com.example.springmvc.mvcLayer.domain.cart.CartItem; import lombok.NoArgsConstructor; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; -@Getter + @Component @NoArgsConstructor public class ShoppingCart { @@ -62,4 +61,12 @@ public int getCount() { } return count; } + + public Map getCartItems() { + return new HashMap<>(cartItems); + } + + public Integer getTotalPrice() { + return totalPrice; + } } \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/configuration/MvcConfiguration.java b/src/main/java/com/example/springmvc/mvcLayer/configuration/MvcConfiguration.java similarity index 92% rename from src/main/java/com/example/springmvc/configuration/MvcConfiguration.java rename to src/main/java/com/example/springmvc/mvcLayer/configuration/MvcConfiguration.java index 4165ed9..6268dca 100644 --- a/src/main/java/com/example/springmvc/configuration/MvcConfiguration.java +++ b/src/main/java/com/example/springmvc/mvcLayer/configuration/MvcConfiguration.java @@ -1,4 +1,4 @@ -package com.example.springmvc.configuration; +package com.example.springmvc.mvcLayer.configuration; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; diff --git a/src/main/java/com/example/springmvc/mvcLayer/configuration/SecurityConfiguration.java b/src/main/java/com/example/springmvc/mvcLayer/configuration/SecurityConfiguration.java new file mode 100644 index 0000000..dcf4bae --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/configuration/SecurityConfiguration.java @@ -0,0 +1,44 @@ +package com.example.springmvc.mvcLayer.configuration; + +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; + +@EnableWebSecurity +@RequiredArgsConstructor +public class SecurityConfiguration extends WebSecurityConfigurerAdapter { + private final UserDetailsService userDetailsService; + + + @Override + protected void configure(HttpSecurity http) throws Exception { + http.authorizeRequests() + .antMatchers("/user/admin/**").hasAnyRole("ADMIN") + .antMatchers("/product/form/**", "/category/form/**").hasAnyRole("ADMIN", "MANAGER") + .antMatchers("/login/**").authenticated() + .anyRequest().permitAll() + .and() + .formLogin() + .defaultSuccessUrl("/product/list") + .and() + .logout().logoutSuccessUrl("/product/list"); + } + + @Bean + public BCryptPasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider(); + authenticationProvider.setUserDetailsService(userDetailsService); + authenticationProvider.setPasswordEncoder(passwordEncoder()); + return authenticationProvider; + } +} diff --git a/src/main/java/com/example/springmvc/controller/CategoryController.java b/src/main/java/com/example/springmvc/mvcLayer/controller/CategoryController.java similarity index 59% rename from src/main/java/com/example/springmvc/controller/CategoryController.java rename to src/main/java/com/example/springmvc/mvcLayer/controller/CategoryController.java index ee12e05..88e4f68 100644 --- a/src/main/java/com/example/springmvc/controller/CategoryController.java +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/CategoryController.java @@ -1,8 +1,7 @@ -package com.example.springmvc.controller; +package com.example.springmvc.mvcLayer.controller; -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -import com.example.springmvc.service.CategoryService; +import com.example.springmvc.mvcLayer.domain.Category; +import com.example.springmvc.mvcLayer.service.CategoryService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -12,14 +11,14 @@ import java.util.List; -import static com.example.springmvc.domain.constans.ConstanceName.*; +import static com.example.springmvc.mvcLayer.domain.constans.ConstanceName.*; @AllArgsConstructor @Controller @RequestMapping(CATEGORY) public class CategoryController { - private CategoryService categoryService; + private final CategoryService categoryService; @GetMapping(FORM) public String addViewToCreateCategory(Model model, @ModelAttribute("error") String error) { @@ -31,10 +30,10 @@ public String addViewToCreateCategory(Model model, @ModelAttribute("error") Stri public RedirectView createCategory(@RequestParam String title, RedirectAttributes attributes) { if (title.isEmpty()) { attributes.addFlashAttribute("error", "Заполните поле название категории"); - return new RedirectView("/form"); + return new RedirectView(CATEGORY+FORM); } categoryService.addCategory(title); - return new RedirectView("/category/list"); + return new RedirectView(CATEGORY+LIST); } @GetMapping(LIST) @@ -43,14 +42,4 @@ public String findAllCategory(Model model) { model.addAttribute("categories", categories); return "category/list"; } - - @GetMapping(FIND) - public String findProductByCategoryId(@RequestParam Integer categoryId, Model model) { - List products = categoryService.findProductsByCategoryId(categoryId); - List category = categoryService.findCategory(); - model.addAttribute("category", category); - model.addAttribute("products", products); - - return "product/list"; - } } diff --git a/src/main/java/com/example/springmvc/mvcLayer/controller/OrderController.java b/src/main/java/com/example/springmvc/mvcLayer/controller/OrderController.java new file mode 100644 index 0000000..ebbf106 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/OrderController.java @@ -0,0 +1,47 @@ +package com.example.springmvc.mvcLayer.controller; + +import com.example.springmvc.mvcLayer.component.ShoppingCart; +import com.example.springmvc.mvcLayer.domain.Address; +import com.example.springmvc.mvcLayer.domain.Order; +import com.example.springmvc.mvcLayer.service.OrderService; +import lombok.AllArgsConstructor; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +import static com.example.springmvc.mvcLayer.domain.constans.ConstanceName.FORM; +import static com.example.springmvc.mvcLayer.domain.constans.ConstanceName.LIST; + +@Controller +@AllArgsConstructor +@SessionAttributes("shoppingCart") +@RequestMapping("/order") +public class OrderController { + + private final OrderService orderService; + + @GetMapping(LIST) + public String getAllOrders(Model model) { + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + List orders = orderService.getAllOrders(name); + model.addAttribute("orders", orders); + return "order/list"; + } + + @GetMapping(FORM) + public String createOrderView(Model model, @ModelAttribute ShoppingCart shoppingCart) { + model.addAttribute("address", new Address()); + return "order/newOrder"; + } + + @PostMapping(FORM) + public String createOrder(@ModelAttribute Address address, + @ModelAttribute ShoppingCart shoppingCart) { + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + orderService.save(shoppingCart, address, name); + return "redirect:/order/list"; + } +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/controller/ProductController.java b/src/main/java/com/example/springmvc/mvcLayer/controller/ProductController.java new file mode 100644 index 0000000..337c7c9 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/ProductController.java @@ -0,0 +1,108 @@ +package com.example.springmvc.mvcLayer.controller; + + +import com.example.springmvc.mvcLayer.domain.Category; +import com.example.springmvc.mvcLayer.domain.Product; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.domain.search.ProductSearchCondition; +import com.example.springmvc.mvcLayer.service.CategoryService; +import com.example.springmvc.mvcLayer.service.ProductService; +import lombok.AllArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.view.RedirectView; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; + +import static com.example.springmvc.mvcLayer.domain.constans.ConstanceName.*; + +@AllArgsConstructor +@Controller +@RequestMapping(PRODUCT) +public class ProductController { + + private final ProductService productService; + private final CategoryService categoryService; + + + @GetMapping(LIST) + public String getListProducts(@ModelAttribute ProductSearchCondition searchCondition, Model model) { + Page page = productService.findAllBySearchConditional(searchCondition); + productService.pagination(searchCondition, model, page); + return "product/list"; + } + + @GetMapping(LIST + "/{catId}") + public String getProductsByCategoryId(@PathVariable Integer catId, Model model) { + ProductSearchCondition searchCondition = new ProductSearchCondition(); + Page page = productService.findProductsByCategoryId(catId, searchCondition); + productService.pagination(searchCondition, model, page); + return "product/list"; + } + + @GetMapping(FORM) + public String getProductForm(Model model, @RequestParam(required = false) Integer id, + @ModelAttribute("error") String error) { + List categories = categoryService.findCategory(); + model.addAttribute("categories", categories); + model.addAttribute("error", error); + if (id != null) { + ProductDto productDtoById = productService.findProductDtoById(id); + model.addAttribute("product", productDtoById); + } else { + model.addAttribute("product", new ProductDto()); + } + return "product/form"; + } + + @PostMapping(FORM) + public RedirectView saveProduct(@ModelAttribute ProductDto product, RedirectAttributes attributes, + @RequestParam(required = false) MultipartFile image) { + boolean redirectView = getRedirectView(product.getTitle(), product.getPrice(), attributes, image); + if (redirectView) { + return new RedirectView("/product/form"); + } + productService.saveProductAndImage(product, image); + return new RedirectView("/product/list"); + } + + @ExceptionHandler(Exception.class) + public String handleError(HttpServletRequest req, Exception ex) { + System.err.println("Request: " + req.getRequestURL() + " raised " + ex); + return "error"; + } + + @GetMapping(DELETE) + public RedirectView deleteProductById(@RequestParam Integer id) { + productService.deleteProductById(id); + return new RedirectView("/product/list"); + } + + @GetMapping(FILTER) + public String filterProductsByTitleAndByMaxAndMinPrice(@ModelAttribute ProductSearchCondition searchCondition, + @RequestParam(required = false) String title, + @RequestParam(required = false) Integer minPrice, + @RequestParam(required = false) Integer maxPrice, Model model) { + Page page = productService.findProductsByTitleAndByMaxAndMinPriceBySearchConditional( + searchCondition, title, minPrice, maxPrice); + productService.pagination(searchCondition, model, page); + return ("product/list"); + } + + private boolean getRedirectView(String title, Integer price, RedirectAttributes attributes, MultipartFile image) { + if (title.isEmpty()) { + attributes.addFlashAttribute("error", "Заполните поле с названием продукта"); + return true; + } + if (price == null) { + attributes.addFlashAttribute("error", "Заполните поле с ценой продукта"); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/controller/ShoppingCartController.java b/src/main/java/com/example/springmvc/mvcLayer/controller/ShoppingCartController.java similarity index 85% rename from src/main/java/com/example/springmvc/controller/ShoppingCartController.java rename to src/main/java/com/example/springmvc/mvcLayer/controller/ShoppingCartController.java index c8ce4c2..1b08d4d 100644 --- a/src/main/java/com/example/springmvc/controller/ShoppingCartController.java +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/ShoppingCartController.java @@ -1,9 +1,9 @@ -package com.example.springmvc.controller; +package com.example.springmvc.mvcLayer.controller; -import com.example.springmvc.component.ShoppingCart; -import com.example.springmvc.domain.CartItem; -import com.example.springmvc.domain.dto.ProductDto; -import com.example.springmvc.service.ProductService; +import com.example.springmvc.mvcLayer.component.ShoppingCart; +import com.example.springmvc.mvcLayer.domain.cart.CartItem; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.service.ProductService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; diff --git a/src/main/java/com/example/springmvc/mvcLayer/controller/UserController.java b/src/main/java/com/example/springmvc/mvcLayer/controller/UserController.java new file mode 100644 index 0000000..0977c05 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/UserController.java @@ -0,0 +1,58 @@ +package com.example.springmvc.mvcLayer.controller; + +import com.example.springmvc.mvcLayer.domain.security.User; +import com.example.springmvc.mvcLayer.service.UserService; +import lombok.AllArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +@AllArgsConstructor +@RequestMapping("/user") +public class UserController { + + private final UserService userService; + + @GetMapping("/admin") + public String getAllUsers(@RequestParam(required = false) Integer pageNum, Model model) { + final int pageSize = 5; + Pageable pageRequest = PageRequest.of(pageNum == null ? 0 : pageNum, pageSize); + Page page = userService.findAllByPage(pageRequest); + model.addAttribute("page", page); + return "user/admin"; + } + + @GetMapping("/registration") + public String createModelRegistration(Model model) { + model.addAttribute("user", new User()); + return "user/registration"; + } + + @PostMapping("/registration") + public String registrationUser(User user) { + userService.saveUser(user); + return "redirect:/login"; + } + + @GetMapping("/enable") + public String setEnableUser(@RequestParam Long userId, @RequestParam Boolean enable) { + userService.setEnable(userId, enable); + return "redirect:/user/admin"; + } + + @GetMapping("/account") + public String getUserAccount(Model model) { + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + User user = userService.findByUsername(name); + model.addAttribute("user", user); + return "user/personalAccount"; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/sessionItem/Cart.java b/src/main/java/com/example/springmvc/mvcLayer/controller/advice/GlobalCart.java similarity index 64% rename from src/main/java/com/example/springmvc/sessionItem/Cart.java rename to src/main/java/com/example/springmvc/mvcLayer/controller/advice/GlobalCart.java index 95a60ce..d78ddd6 100644 --- a/src/main/java/com/example/springmvc/sessionItem/Cart.java +++ b/src/main/java/com/example/springmvc/mvcLayer/controller/advice/GlobalCart.java @@ -1,11 +1,11 @@ -package com.example.springmvc.sessionItem; +package com.example.springmvc.mvcLayer.controller.advice; -import com.example.springmvc.component.ShoppingCart; +import com.example.springmvc.mvcLayer.component.ShoppingCart; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ModelAttribute; @ControllerAdvice -public class Cart { +public class GlobalCart { @ModelAttribute("shoppingCart") public ShoppingCart shoppingCart() { diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/Address.java b/src/main/java/com/example/springmvc/mvcLayer/domain/Address.java new file mode 100644 index 0000000..16ce928 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/Address.java @@ -0,0 +1,32 @@ +package com.example.springmvc.mvcLayer.domain; + +import lombok.*; + +import javax.persistence.*; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "address") +@EqualsAndHashCode(exclude = {"id"}) +public class Address { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "city") + private String city; + + @Column(name = "street") + private String street; + + @Column(name = "house") + private int house; + + @Column(name = "apartment") + private int apartment; + +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/domain/Category.java b/src/main/java/com/example/springmvc/mvcLayer/domain/Category.java similarity index 86% rename from src/main/java/com/example/springmvc/domain/Category.java rename to src/main/java/com/example/springmvc/mvcLayer/domain/Category.java index 4048ac3..b4d48c5 100644 --- a/src/main/java/com/example/springmvc/domain/Category.java +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/Category.java @@ -1,20 +1,21 @@ -package com.example.springmvc.domain; +package com.example.springmvc.mvcLayer.domain; import com.fasterxml.jackson.annotation.JsonBackReference; import lombok.*; import javax.persistence.*; +import javax.validation.constraints.NotBlank; import java.util.List; import java.util.Set; -@AllArgsConstructor -@NoArgsConstructor @Data @Entity @Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "category") @ToString(exclude = {"subCategories"}) @EqualsAndHashCode(exclude = {"id", "subCategories"}) -@Table(name = "category") public class Category { @Id @@ -22,6 +23,7 @@ public class Category { private Integer id; @Column(name = "title") + @NotBlank(message = "Название обязательно") private String title; @ManyToOne diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/Order.java b/src/main/java/com/example/springmvc/mvcLayer/domain/Order.java new file mode 100644 index 0000000..0f26abf --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/Order.java @@ -0,0 +1,48 @@ +package com.example.springmvc.mvcLayer.domain; + +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.domain.security.User; +import com.vladmihalcea.hibernate.type.json.JsonBinaryType; +import lombok.*; +import org.hibernate.annotations.Type; +import org.hibernate.annotations.TypeDef; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.LocalDate; +import java.util.List; + +@Data +@Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "orders") +@TypeDef(name = "jsonb", typeClass = JsonBinaryType.class) +@ToString(exclude = {"userId", "address", "cart"}) +@EqualsAndHashCode(exclude = {"id", "userId", "address", "cart"}) +public class Order implements Serializable { + + @Id + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @Column(name = "status") + private String status; + + @OneToOne + @JoinColumn(name = "address_id") + private Address address; + + @JoinColumn(name = "user_id") + @ManyToOne(fetch = FetchType.LAZY) + private User userId; + + @Type(type = "jsonb") + @Column(columnDefinition = "jsonb") + private List cart; + + @Column(name = "date") + private LocalDate date; +} diff --git a/src/main/java/com/example/springmvc/domain/Product.java b/src/main/java/com/example/springmvc/mvcLayer/domain/Product.java similarity index 85% rename from src/main/java/com/example/springmvc/domain/Product.java rename to src/main/java/com/example/springmvc/mvcLayer/domain/Product.java index 179b1f0..03c871f 100644 --- a/src/main/java/com/example/springmvc/domain/Product.java +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/Product.java @@ -1,4 +1,4 @@ -package com.example.springmvc.domain; +package com.example.springmvc.mvcLayer.domain; import lombok.*; @@ -8,28 +8,33 @@ import java.util.HashSet; import java.util.Set; -@Builder -@ToString(exclude = {"categories"}) -@EqualsAndHashCode(exclude = {"id", "categories"}) + @Data -@AllArgsConstructor -@NoArgsConstructor @Entity +@Builder +@NoArgsConstructor +@AllArgsConstructor @Table(name = "product") +@ToString(exclude = {"categories"}) +@EqualsAndHashCode(exclude = {"id", "categories"}) public class Product { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Integer id; + @NotBlank(message = "Название обязательно") @Column(name = "title") private String title; + @NotNull(message = "Цена обязательна") @Column(name = "price") private Integer price; + @Column(name = "image") private String image; + @ManyToMany @JoinTable( name = "product_category", @@ -42,8 +47,4 @@ public Product(String title, int price) { this.title = title; this.price = price; } -// @Override -// public String toString() { -// return "{" + id + ", " + title + ", " + price + "," + category + "," + image + "}"; -// } } diff --git a/src/main/java/com/example/springmvc/domain/CartItem.java b/src/main/java/com/example/springmvc/mvcLayer/domain/cart/CartItem.java similarity index 76% rename from src/main/java/com/example/springmvc/domain/CartItem.java rename to src/main/java/com/example/springmvc/mvcLayer/domain/cart/CartItem.java index dc2074c..7918023 100644 --- a/src/main/java/com/example/springmvc/domain/CartItem.java +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/cart/CartItem.java @@ -1,7 +1,6 @@ -package com.example.springmvc.domain; +package com.example.springmvc.mvcLayer.domain.cart; -import com.example.springmvc.domain.dto.ProductDto; -import lombok.AllArgsConstructor; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; import lombok.Getter; @Getter diff --git a/src/main/java/com/example/springmvc/domain/constans/ConstanceName.java b/src/main/java/com/example/springmvc/mvcLayer/domain/constans/ConstanceName.java similarity index 89% rename from src/main/java/com/example/springmvc/domain/constans/ConstanceName.java rename to src/main/java/com/example/springmvc/mvcLayer/domain/constans/ConstanceName.java index e65e0fb..000042f 100644 --- a/src/main/java/com/example/springmvc/domain/constans/ConstanceName.java +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/constans/ConstanceName.java @@ -1,4 +1,4 @@ -package com.example.springmvc.domain.constans; +package com.example.springmvc.mvcLayer.domain.constans; import lombok.NoArgsConstructor; diff --git a/src/main/java/com/example/springmvc/domain/dto/CategoryDto.java b/src/main/java/com/example/springmvc/mvcLayer/domain/dto/CategoryDto.java similarity index 85% rename from src/main/java/com/example/springmvc/domain/dto/CategoryDto.java rename to src/main/java/com/example/springmvc/mvcLayer/domain/dto/CategoryDto.java index e3bdcd0..d0f239e 100644 --- a/src/main/java/com/example/springmvc/domain/dto/CategoryDto.java +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/dto/CategoryDto.java @@ -1,4 +1,4 @@ -package com.example.springmvc.domain.dto; +package com.example.springmvc.mvcLayer.domain.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/dto/ProductDto.java b/src/main/java/com/example/springmvc/mvcLayer/domain/dto/ProductDto.java new file mode 100644 index 0000000..36acd9d --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/dto/ProductDto.java @@ -0,0 +1,19 @@ +package com.example.springmvc.mvcLayer.domain.dto; + +import com.example.springmvc.mvcLayer.domain.Category; +import lombok.*; + +import java.io.Serializable; +import java.util.Set; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(exclude = "categoryDto") +public class ProductDto implements Serializable { + private Integer id; + private String title; + private Integer price; + private Set categoryDto; +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/search/ProductSearchCondition.java b/src/main/java/com/example/springmvc/mvcLayer/domain/search/ProductSearchCondition.java new file mode 100644 index 0000000..93e6769 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/search/ProductSearchCondition.java @@ -0,0 +1,20 @@ +package com.example.springmvc.mvcLayer.domain.search; + +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import lombok.Data; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Sort; + +import java.util.Collections; +import java.util.List; + +@Data +public class ProductSearchCondition { + private Sort.Direction sortDirection=Sort.Direction.ASC; + private String sortField="title"; + + private int pageNum =1; + private Integer pageSize=10; + +// private Page page; +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/security/Role.java b/src/main/java/com/example/springmvc/mvcLayer/domain/security/Role.java new file mode 100644 index 0000000..036f5d3 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/security/Role.java @@ -0,0 +1,20 @@ +package com.example.springmvc.mvcLayer.domain.security; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.persistence.*; + +@Data +@Entity +@Table(name = "role") +@EqualsAndHashCode(exclude = {"id"}) +public class Role { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/domain/security/User.java b/src/main/java/com/example/springmvc/mvcLayer/domain/security/User.java new file mode 100644 index 0000000..c0cb1f6 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/domain/security/User.java @@ -0,0 +1,41 @@ +package com.example.springmvc.mvcLayer.domain.security; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.ToString; + +import javax.persistence.*; +import javax.validation.constraints.NotBlank; +import java.util.Collection; + +@Data +@Entity +@NoArgsConstructor +@Table(name = "users") +@ToString(exclude = "roles") +@EqualsAndHashCode(exclude = {"id", "roles"}) +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotBlank(message = "Имя обязательно") +// @Size(min = 1,max = 30) + private String username; + +// @Size(min = 6,max = 80) + @NotBlank(message = "Пароль обязательно") + private String password; + + @NotBlank(message = "email обязательно") + private String email; + + private boolean enabled = true; + + @ManyToMany + @JoinTable(name = "user_role", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "role_id")) + private Collection roles; +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/repository/AddressRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/AddressRepository.java new file mode 100644 index 0000000..bd65030 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/AddressRepository.java @@ -0,0 +1,9 @@ +package com.example.springmvc.mvcLayer.repository; + +import com.example.springmvc.mvcLayer.domain.Address; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface AddressRepository extends JpaRepository { +} diff --git a/src/main/java/com/example/springmvc/repository/CategoryRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/CategoryRepository.java similarity index 56% rename from src/main/java/com/example/springmvc/repository/CategoryRepository.java rename to src/main/java/com/example/springmvc/mvcLayer/repository/CategoryRepository.java index 6b300c8..e9a5473 100644 --- a/src/main/java/com/example/springmvc/repository/CategoryRepository.java +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/CategoryRepository.java @@ -1,8 +1,6 @@ -package com.example.springmvc.repository; +package com.example.springmvc.mvcLayer.repository; -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.dto.CategoryDto; +import com.example.springmvc.mvcLayer.domain.Category; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -14,6 +12,9 @@ public interface CategoryRepository extends JpaRepository { Optional findCategoryByTitle(String title); - Set findByProducts_Id(Integer productId); + + Set findCategoryByIdIn(Set ids); + +// Page findProductsByIdCategory(Pageable pageable); } diff --git a/src/main/java/com/example/springmvc/mvcLayer/repository/OrderRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/OrderRepository.java new file mode 100644 index 0000000..8eed25b --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/OrderRepository.java @@ -0,0 +1,13 @@ +package com.example.springmvc.mvcLayer.repository; + +import com.example.springmvc.mvcLayer.domain.Order; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface OrderRepository extends JpaRepository { + + List findOrdersByUserId_Username(String userName); +} diff --git a/src/main/java/com/example/springmvc/repository/ProductRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/ProductRepository.java similarity index 52% rename from src/main/java/com/example/springmvc/repository/ProductRepository.java rename to src/main/java/com/example/springmvc/mvcLayer/repository/ProductRepository.java index 8c2f398..3334703 100644 --- a/src/main/java/com/example/springmvc/repository/ProductRepository.java +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/ProductRepository.java @@ -1,7 +1,7 @@ -package com.example.springmvc.repository; +package com.example.springmvc.mvcLayer.repository; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.domain.Category; +import com.example.springmvc.mvcLayer.domain.Product; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -9,20 +9,20 @@ import java.util.List; import java.util.Optional; -import java.util.Set; @Repository public interface ProductRepository extends JpaRepository { - List findAll(); + // List findAll(); + Page findProductsByCategories(Pageable pageable, Category category); + Optional findById(Integer id); void deleteById(Integer id); - List findProductsByTitleContainingIgnoreCaseAndPriceBetween(String title, Integer minPrice, Integer maxPrice); - - Set findByCategories_Id(Integer categoryId); - Page findAll(Pageable pageable); + + Page findProductsByTitleContainingIgnoreCaseAndPriceBetween( + String title, Integer minPrice, Integer maxPrice, Pageable pageable); } diff --git a/src/main/java/com/example/springmvc/mvcLayer/repository/RoleRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/RoleRepository.java new file mode 100644 index 0000000..b0ded53 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/RoleRepository.java @@ -0,0 +1,13 @@ +package com.example.springmvc.mvcLayer.repository; + +import com.example.springmvc.mvcLayer.domain.security.Role; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface RoleRepository extends JpaRepository { + + Optional findByNameIgnoreCase(String name); +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/repository/UserRepository.java b/src/main/java/com/example/springmvc/mvcLayer/repository/UserRepository.java new file mode 100644 index 0000000..f91aea2 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/repository/UserRepository.java @@ -0,0 +1,14 @@ +package com.example.springmvc.mvcLayer.repository; + +import com.example.springmvc.mvcLayer.domain.security.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface UserRepository extends JpaRepository { + + Optional findByUsername(String username); + +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/CategoryService.java b/src/main/java/com/example/springmvc/mvcLayer/service/CategoryService.java new file mode 100644 index 0000000..efef088 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/CategoryService.java @@ -0,0 +1,18 @@ +package com.example.springmvc.mvcLayer.service; + +import com.example.springmvc.mvcLayer.domain.Category; + +import java.util.List; +import java.util.Set; + +public interface CategoryService { + + List findCategory(); + + void addCategory(String title); + + Set findCategoryById(Set id); + + Set getCategoryIdList(Set categories); + +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/OrderService.java b/src/main/java/com/example/springmvc/mvcLayer/service/OrderService.java new file mode 100644 index 0000000..8b36f26 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/OrderService.java @@ -0,0 +1,13 @@ +package com.example.springmvc.mvcLayer.service; + +import com.example.springmvc.mvcLayer.component.ShoppingCart; +import com.example.springmvc.mvcLayer.domain.Address; +import com.example.springmvc.mvcLayer.domain.Order; + +import java.util.List; + +public interface OrderService { + + void save(ShoppingCart shoppingCart, Address address, String name ); + List getAllOrders(String name); +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/ProductService.java b/src/main/java/com/example/springmvc/mvcLayer/service/ProductService.java new file mode 100644 index 0000000..b114852 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/ProductService.java @@ -0,0 +1,30 @@ +package com.example.springmvc.mvcLayer.service; + +import com.example.springmvc.mvcLayer.domain.Product; +import com.example.springmvc.mvcLayer.domain.search.ProductSearchCondition; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import org.springframework.data.domain.Page; +import org.springframework.ui.Model; +import org.springframework.web.multipart.MultipartFile; + +import java.util.Optional; + +public interface ProductService { + + Page findProductsByCategoryId(Integer catId,ProductSearchCondition searchCondition); + + Page findAllBySearchConditional(ProductSearchCondition searchCondition); + + Product saveProductAndImage(ProductDto product, MultipartFile image); + + Optional findProductById(Integer id); + + ProductDto findProductDtoById(Integer id); + + void deleteProductById(Integer id); + + Page findProductsByTitleAndByMaxAndMinPriceBySearchConditional( + ProductSearchCondition searchCondition, String title, Integer minPrice, Integer maxPrice); + + void pagination(ProductSearchCondition searchCondition, Model model, Page page); +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/RoleService.java b/src/main/java/com/example/springmvc/mvcLayer/service/RoleService.java new file mode 100644 index 0000000..503d479 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/RoleService.java @@ -0,0 +1,8 @@ +package com.example.springmvc.mvcLayer.service; + +import com.example.springmvc.mvcLayer.domain.security.Role; + +public interface RoleService { + + Role findByName(String name); +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/UserService.java b/src/main/java/com/example/springmvc/mvcLayer/service/UserService.java new file mode 100644 index 0000000..8a670f0 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/UserService.java @@ -0,0 +1,16 @@ +package com.example.springmvc.mvcLayer.service; + +import com.example.springmvc.mvcLayer.domain.security.User; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface UserService { + + User findByUsername(String username); + + User saveUser(User user); + + Page findAllByPage(Pageable pageRequest); + + void setEnable(Long userId, Boolean enable); +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/CategoryServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/CategoryServiceImpl.java new file mode 100644 index 0000000..1b177d3 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/CategoryServiceImpl.java @@ -0,0 +1,43 @@ +package com.example.springmvc.mvcLayer.service.impl; + +import com.example.springmvc.mvcLayer.domain.Category; +import com.example.springmvc.mvcLayer.repository.CategoryRepository; +import com.example.springmvc.mvcLayer.service.CategoryService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; + +@Service +@AllArgsConstructor +public class CategoryServiceImpl implements CategoryService { + + private final CategoryRepository categoryRepository; + + @Override + public List findCategory() { + return categoryRepository.findAll(); + } + + @Override + @Transactional + public void addCategory(String title) { + Optional categoryByTitle = categoryRepository.findCategoryByTitle(title); + if (categoryByTitle.isEmpty()) { + categoryRepository.save(new Category(title)); + } + } + + @Override + public Set findCategoryById(Set id) { + return categoryRepository.findCategoryByIdIn(id); + } + + @Override + public Set getCategoryIdList(Set categories) { + Set ids = new HashSet<>(); + categories.forEach(category -> ids.add(category.getId())); + return ids; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/OrderServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/OrderServiceImpl.java new file mode 100644 index 0000000..28630a7 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/OrderServiceImpl.java @@ -0,0 +1,59 @@ +package com.example.springmvc.mvcLayer.service.impl; + +import com.example.springmvc.mvcLayer.component.ShoppingCart; +import com.example.springmvc.mvcLayer.domain.Address; +import com.example.springmvc.mvcLayer.domain.Order; +import com.example.springmvc.mvcLayer.domain.cart.CartItem; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.domain.security.User; +import com.example.springmvc.mvcLayer.repository.AddressRepository; +import com.example.springmvc.mvcLayer.repository.OrderRepository; +import com.example.springmvc.mvcLayer.service.OrderService; +import com.example.springmvc.mvcLayer.service.UserService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Service +@AllArgsConstructor +public class OrderServiceImpl implements OrderService { + + private final OrderRepository orderRepository; + + private final UserService userService; + + private final AddressRepository addressRepository; + + @Override + @Transactional + public void save(ShoppingCart shoppingCart, Address address, String name) { + Address save = addressRepository.save(address); + User user = userService.findByUsername(name); + Order order = new Order(); + List cart = new ArrayList<>(); + Map cartItems = shoppingCart.getCartItems(); + for (CartItem value : cartItems.values()) { + ProductDto product = value.getProduct(); + cart.add(product); + shoppingCart.deleteCartItem(product.getId()); + } + order.setStatus("new"); + order.setAddress(save); + order.setUserId(user); + order.setCart(cart); + order.setDate(LocalDate.now()); + orderRepository.save(order); + shoppingCart.getCartItems().clear(); + } + + @Override + public List getAllOrders(String name) { + return orderRepository.findOrdersByUserId_Username(name); + } + +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/ProductServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/ProductServiceImpl.java new file mode 100644 index 0000000..087ea97 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/ProductServiceImpl.java @@ -0,0 +1,137 @@ +package com.example.springmvc.mvcLayer.service.impl; + +import com.example.springmvc.mvcLayer.domain.Category; +import com.example.springmvc.mvcLayer.domain.Product; +import com.example.springmvc.mvcLayer.domain.search.ProductSearchCondition; +import com.example.springmvc.mvcLayer.domain.dto.ProductDto; +import com.example.springmvc.mvcLayer.repository.CategoryRepository; +import com.example.springmvc.mvcLayer.repository.ProductRepository; +import com.example.springmvc.mvcLayer.service.CategoryService; +import com.example.springmvc.mvcLayer.service.ProductService; +import com.example.springmvc.mvcLayer.utils.FileUtils; +import lombok.AllArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.ui.Model; +import org.springframework.web.multipart.MultipartFile; + +import java.nio.file.Path; +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +@AllArgsConstructor +@Service +public class ProductServiceImpl implements ProductService { + + private final ProductRepository productRepository; + private final CategoryService categoryService; + private final CategoryRepository categoryRepository; + + + @Override + @Transactional + public Product saveProductAndImage(ProductDto productDto, MultipartFile image) { + Product product = convertProductDtoInProduct(productDto); + Product savedProduct = productRepository.save(product); + if (image != null && !image.isEmpty()) { + Path pathImage = FileUtils.saveProductImage(image); + savedProduct.setImage(pathImage.toString()); + productRepository.save(savedProduct); + } + return savedProduct; + } + + private Product convertProductDtoInProduct(ProductDto productDto) { + Integer id = productDto.getId(); + if (id != null) { + Product product = dtoProductConvertToProduct(productDto); + product.setId(productDto.getId()); + return product; + } + return dtoProductConvertToProduct(productDto); + } + + private Product dtoProductConvertToProduct(ProductDto productDto) { + return Product.builder().title(productDto.getTitle()) + .price(productDto.getPrice()) + .categories(categoryService.findCategoryById(productDto.getCategoryDto())) + .build(); + } + + @Override + public Optional findProductById(Integer id) { + return productRepository.findById(id); + } + + @Override + @Transactional + public ProductDto findProductDtoById(Integer id) { + Optional productById = findProductById(id); + return productConvertToDTOProduct(productById.get()); + } + + private ProductDto productConvertToDTOProduct(Product entity) { + return ProductDto.builder().id(entity.getId()) + .title(entity.getTitle()) + .price(entity.getPrice()) + .categoryDto(categoryService.getCategoryIdList(entity.getCategories())) + .build(); + } + + @Override + public void deleteProductById(Integer id) { + productRepository.deleteById(id); + } + + @Override + @Transactional + public Page findProductsByCategoryId(Integer catId, ProductSearchCondition searchCondition) { + Optional byId = categoryRepository.findById(catId); + Pageable pageable = getPageable(searchCondition); + return productRepository.findProductsByCategories(pageable, byId.get()); + } + + @Override + public Page findAllBySearchConditional(ProductSearchCondition searchCondition) { + Pageable pageRequest = getPageable(searchCondition); + return productRepository.findAll(pageRequest); + } + + private Pageable getPageable(ProductSearchCondition searchCondition) { + return PageRequest.of(searchCondition.getPageNum() - 1, + searchCondition.getPageSize(), + Sort.by(searchCondition.getSortDirection(), searchCondition.getSortField())); + } + + @Override + public Page findProductsByTitleAndByMaxAndMinPriceBySearchConditional( + ProductSearchCondition searchCondition, String title, Integer minPrice, Integer maxPrice) { + if (Objects.isNull(minPrice)) { + minPrice = 0; + } + if (Objects.isNull(maxPrice)) { + maxPrice = Integer.MAX_VALUE; + } + Pageable pageRequest = getPageable(searchCondition); + return productRepository.findProductsByTitleContainingIgnoreCaseAndPriceBetween(title, minPrice, maxPrice, pageRequest); + } + + @Override + public void pagination(ProductSearchCondition searchCondition, Model model, Page page) { + int totalPages = page.getTotalPages(); + if (totalPages > 0) { + List pageNumbers = IntStream.rangeClosed(1, totalPages) + .boxed() + .collect(Collectors.toList()); + model.addAttribute("pageNumbers", pageNumbers); + } + model.addAttribute("pageNum", searchCondition.getPageNum()); + model.addAttribute("page", page); + model.addAttribute("pageSize", searchCondition.getPageSize()); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/RoleServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/RoleServiceImpl.java new file mode 100644 index 0000000..4c64872 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/RoleServiceImpl.java @@ -0,0 +1,26 @@ +package com.example.springmvc.mvcLayer.service.impl.security; + +import com.example.springmvc.mvcLayer.domain.security.Role; +import com.example.springmvc.mvcLayer.repository.RoleRepository; +import com.example.springmvc.mvcLayer.service.RoleService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +import javax.persistence.EntityNotFoundException; +import java.util.Optional; + +@Service +@AllArgsConstructor +public class RoleServiceImpl implements RoleService { + + private final RoleRepository roleRepository; + + @Override + public Role findByName(String name) { + Optional byNameIgnoreCase = roleRepository.findByNameIgnoreCase(name); + if (byNameIgnoreCase.isEmpty()) { + throw new EntityNotFoundException("Role witch name" + name + " not found"); + } + return byNameIgnoreCase.get(); + } +} diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserDetailsServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserDetailsServiceImpl.java new file mode 100644 index 0000000..b9f901e --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserDetailsServiceImpl.java @@ -0,0 +1,40 @@ +package com.example.springmvc.mvcLayer.service.impl.security; + +import com.example.springmvc.mvcLayer.domain.security.Role; +import com.example.springmvc.mvcLayer.repository.UserRepository; +import lombok.AllArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.stream.Collectors; + +@Component +@AllArgsConstructor +public class UserDetailsServiceImpl implements UserDetailsService { + + private final UserRepository userRepository; + + @Override + @Transactional + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + com.example.springmvc.mvcLayer.domain.security.User user = userRepository.findByUsername(username) + .orElseThrow(() -> new UsernameNotFoundException(String.format("User '%s' not found", username))); + return new User( + user.getUsername(), user.getPassword(), + user.isEnabled(), true, true, true, + mapRolesToAuthorities(user.getRoles()) + ); + } + + private Collection mapRolesToAuthorities(Collection roles) { + return roles.stream().map(role -> new SimpleGrantedAuthority(role.getName())) + .collect(Collectors.toList()); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserServiceImpl.java b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserServiceImpl.java new file mode 100644 index 0000000..19ff560 --- /dev/null +++ b/src/main/java/com/example/springmvc/mvcLayer/service/impl/security/UserServiceImpl.java @@ -0,0 +1,65 @@ +package com.example.springmvc.mvcLayer.service.impl.security; + +import com.example.springmvc.mvcLayer.domain.security.Role; +import com.example.springmvc.mvcLayer.domain.security.User; +import com.example.springmvc.mvcLayer.repository.UserRepository; +import com.example.springmvc.mvcLayer.service.RoleService; +import com.example.springmvc.mvcLayer.service.UserService; +import lombok.AllArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.persistence.EntityNotFoundException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Optional; + +@Service +@AllArgsConstructor +public class UserServiceImpl implements UserService { + + private final UserRepository userRepository; + private final RoleService roleService; + private final PasswordEncoder passwordEncoder; + + + @Override + public User findByUsername(String username) { + Optional byUsername = userRepository.findByUsername(username); + if (byUsername.isEmpty()) { + throw new UsernameNotFoundException(String.format("User '%s' not found", username)); + } + return byUsername.get(); + } + + @Override + @Transactional + public User saveUser(User user) { + Role userRole = roleService.findByName("ROLE_USER"); + user.setRoles(new ArrayList<>(Collections.singletonList(userRole))); + user.setPassword(passwordEncoder.encode(user.getPassword())); + + return userRepository.save(user); + } + + @Override + public Page findAllByPage(Pageable pageable) { + return userRepository.findAll(pageable); + } + + @Override + @Transactional + public void setEnable(Long userId, Boolean enable) { + Optional byId = userRepository.findById(userId); + if (byId.isEmpty()) { + throw new EntityNotFoundException("User witch id" + userId + " not found"); + } + User user = byId.get(); + user.setEnabled(enable); + userRepository.save(user); + } +} diff --git a/src/main/java/com/example/springmvc/utils/FileUtils.java b/src/main/java/com/example/springmvc/mvcLayer/utils/FileUtils.java similarity index 96% rename from src/main/java/com/example/springmvc/utils/FileUtils.java rename to src/main/java/com/example/springmvc/mvcLayer/utils/FileUtils.java index a6de6bc..08157be 100644 --- a/src/main/java/com/example/springmvc/utils/FileUtils.java +++ b/src/main/java/com/example/springmvc/mvcLayer/utils/FileUtils.java @@ -1,4 +1,4 @@ -package com.example.springmvc.utils; +package com.example.springmvc.mvcLayer.utils; import org.springframework.web.multipart.MultipartFile; diff --git a/src/main/java/com/example/springmvc/service/CategoryService.java b/src/main/java/com/example/springmvc/service/CategoryService.java deleted file mode 100644 index d19af87..0000000 --- a/src/main/java/com/example/springmvc/service/CategoryService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.example.springmvc.service; - -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.dto.CategoryDto; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -public interface CategoryService { - - void deleteCategory(Integer id); - - void updateCategory(Integer id,String title); - - List findCategory(); - - void addCategory(String title); - - ListfindProductsByCategoryId(Integer id); - - Optional findCategoryById(Integer id); - - Set getCategoryDtoByProductId(Integer productId); - - Set findCategoriesByProductId(Integer id); -} diff --git a/src/main/java/com/example/springmvc/service/ProductService.java b/src/main/java/com/example/springmvc/service/ProductService.java deleted file mode 100644 index ce97188..0000000 --- a/src/main/java/com/example/springmvc/service/ProductService.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.springmvc.service; - -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.search.ProductSearchCondition; -import com.example.springmvc.domain.dto.ProductDto; -import org.springframework.data.domain.Page; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; -import java.util.Optional; -import java.util.Set; - -public interface ProductService { - - Page findAllBySearchConditional(ProductSearchCondition searchCondition); - - Product saveProduct(Product product); - - Product saveProductAndImage(ProductDto product, MultipartFile image); - - List findProducts(); - - Optional findProductById(Integer id); - - ProductDto findProductDtoById(Integer id); - - void deleteProductById(Integer id); - - List findProductsByTitleAndByMaxAndMinPrice(String title, Integer minPrice, Integer maxPrice); - - Set findProductsDtoByCategoryId(Integer categoryId); -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/service/impl/CategoryServiceImpl.java b/src/main/java/com/example/springmvc/service/impl/CategoryServiceImpl.java deleted file mode 100644 index 92397ca..0000000 --- a/src/main/java/com/example/springmvc/service/impl/CategoryServiceImpl.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.example.springmvc.service.impl; - -//import com.example.springmvc.converter.Converter; -//import com.example.springmvc.converter.ConverterCategory; -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.dto.CategoryDto; -import com.example.springmvc.repository.CategoryRepository; -import com.example.springmvc.service.CategoryService; -import com.example.springmvc.service.ProductService; -import lombok.AllArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -@Service -@AllArgsConstructor -public class CategoryServiceImpl implements CategoryService { - - private final CategoryRepository categoryRepository; -// private final ProductService productService; - - @Override - public void deleteCategory(Integer id) { - categoryRepository.deleteById(id); - } - - @Override - @Transactional - public void updateCategory(Integer id, String title) { - Optional byId = categoryRepository.findById(id); - if (byId.isPresent()) { - Category category = byId.get(); - category.setTitle(title); - categoryRepository.save(category); - } - } - - @Override - public List findCategory() { - return categoryRepository.findAll(); - } - - @Override - @Transactional - public void addCategory(String title) { - Optional categoryByTitle = categoryRepository.findCategoryByTitle(title); - if (categoryByTitle.isEmpty()) { - categoryRepository.save(new Category(title)); - } - } - - @Override - public List findProductsByCategoryId(Integer id) { - Optional byId = categoryRepository.findById(id); - Category category = byId.get(); - return category.getProducts(); - } - - @Override - public Optional findCategoryById(Integer id) { - return categoryRepository.findById(id); - } - - @Override - public Set getCategoryDtoByProductId(Integer productId) { - Set categoriesByProductId = categoryRepository.findByProducts_Id(productId); - SetcategoryDtoSet=new HashSet<>(); - for (Category category : categoriesByProductId) { - CategoryDto convert = convert(category); - categoryDtoSet.add(convert); - } - return categoryDtoSet; - } - - @Override - public Set findCategoriesByProductId(Integer id) { - return categoryRepository.findByProducts_Id(id); - } - - public CategoryDto convert(Category category){ - return CategoryDto.builder().id(category.getId()) - .title(category.getTitle()) -// .productsDto(productService.findProductsDtoByCategoryId(category.getId())) - .build(); - - } -} \ No newline at end of file diff --git a/src/main/java/com/example/springmvc/service/impl/ProductServiceImpl.java b/src/main/java/com/example/springmvc/service/impl/ProductServiceImpl.java deleted file mode 100644 index 21d2554..0000000 --- a/src/main/java/com/example/springmvc/service/impl/ProductServiceImpl.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.example.springmvc.service.impl; - -//import com.example.springmvc.converter.Converter; -import com.example.springmvc.converter.ProductConverter; -import com.example.springmvc.domain.Product; -import com.example.springmvc.domain.search.ProductSearchCondition; -import com.example.springmvc.domain.dto.ProductDto; -import com.example.springmvc.repository.ProductRepository; -import com.example.springmvc.service.ProductService; -import com.example.springmvc.utils.FileUtils; -import lombok.AllArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Sort; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; - -import java.nio.file.Path; -import java.util.*; - -@AllArgsConstructor -@Service -public class ProductServiceImpl implements ProductService { - - private final ProductRepository productRepository; - - @Override - public Product saveProduct(Product product) { - return productRepository.save(product); - } - - @Override - @Transactional - public Product saveProductAndImage(ProductDto productDto, MultipartFile image) { - Product product = convertProductDtoInProduct(productDto); - Product savedProduct = productRepository.save(product); - if (image != null && !image.isEmpty()) { - Path pathImage = FileUtils.saveProductImage(image); - savedProduct.setImage(pathImage.toString()); - productRepository.save(savedProduct); - } - return savedProduct; - } - - private Product convertProductDtoInProduct(ProductDto productDto) { - Integer id = productDto.getId(); - if (id != null) { - Product product = findProductById(id).get(); - product.setId(productDto.getId()); - return ProductConverter.dtoProductConvertToProduct(productDto, product); - } - Product product = new Product(); - return ProductConverter.dtoProductConvertToProduct(productDto, product); - } - - @Override - public List findProducts() { - return productRepository.findAll(); - } - - @Override - public Optional findProductById(Integer id) { - return productRepository.findById(id); - } - - @Transactional - @Override - public ProductDto findProductDtoById(Integer id) { - Optional productById = findProductById(id); - - return ProductConverter.productConvertToDtoProduct(productById.get()); - } - - @Override - public void deleteProductById(Integer id) { - productRepository.deleteById(id); - } - - @Override - public List findProductsByTitleAndByMaxAndMinPrice(String title, Integer minPrice, Integer maxPrice) { - if (Objects.isNull(minPrice)) { - minPrice = 0; - } - if (Objects.isNull(maxPrice)) { - maxPrice = Integer.MAX_VALUE; - } - return productRepository.findProductsByTitleContainingIgnoreCaseAndPriceBetween(title, minPrice, maxPrice); - } - - @Override - public Set findProductsDtoByCategoryId(Integer categoryId) { - Set productsByCategoryId = productRepository.findByCategories_Id(categoryId); - SetproductDtoSet=new HashSet<>(); - for (Product product : productsByCategoryId) { - ProductDto productDto = ProductConverter.productConvertToDtoProduct(product); - productDtoSet.add(productDto); - } - return productDtoSet; - } - -// -// private boolean getRedirectView(String title, String price, RedirectAttributes attributes, MultipartFile image) { -// if (title.isEmpty()) { -// attributes.addFlashAttribute("error", "Заполните поле с названием продукта"); -// return true; -// } -// if (price.isEmpty()) { -// attributes.addFlashAttribute("error", "Заполните поле с ценой продукта"); -// return true; -// } -// if (image.isEmpty()) { -// attributes.addFlashAttribute("error", "Заполните поле с фотографией продукта"); -// return true; -// } -// return false; -// } - - @Override - public Page findAllBySearchConditional(ProductSearchCondition searchCondition) { - Pageable pageRequest = PageRequest.of(searchCondition.getPageNum(), - searchCondition.getPageSize(), - Sort.by(searchCondition.getSortDirection(), searchCondition.getSortField())); -// return pageRequest; - return productRepository.findAll(pageRequest); - } - - - //переместил в конвертер -// private ProductDto productConvertToDtoProduct(Product product) { -// return ProductDto.builder().id(product.getId()) -// .title(product.getTitle()) -// .price(product.getPrice()) -// .categories(categoryService.getCategoryDtoByProductId(product.getId())).build(); -// } -// -// private Product dtoProductConvertToProduct(ProductDto productDto, Product product) { -// product.setTitle(productDto.getTitle()); -// product.setPrice(productDto.getPrice()); -// product.setCategories(categoryService.findCategoriesByProductId(productDto.getId())); -// return product; -// } - -} \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b77550b..a75c514 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -10,4 +10,5 @@ spring.flyway.enabled=true spring.flyway.url=jdbc:postgresql://localhost:5435/spring spring.flyway.schemas=public spring.flyway.user=postgres -spring.flyway.password=postgrespass \ No newline at end of file +spring.flyway.password=postgrespass +#spring.jpa.open-in-view=false \ No newline at end of file diff --git a/src/main/resources/db/migration/V1_address_orders_create_rable.sql b/src/main/resources/db/migration/V1_address_orders_create_rable.sql new file mode 100644 index 0000000..062da5e --- /dev/null +++ b/src/main/resources/db/migration/V1_address_orders_create_rable.sql @@ -0,0 +1,43 @@ +create table address +( + id serial + constraint address_pk + primary key, + city text not null, + street text not null, + house integer not null, + apartment integer not null +); + +alter table address + owner to postgres; + +create table orders +( + id serial + constraint orders_pk + primary key, + status text not null, + address_id integer not null + constraint orders_address_id_fk + references address + on delete cascade, + user_id integer not null + constraint orders_users_id_fk + references users, + cart jsonb not null, + date date not null +); + +alter table orders + owner to postgres; + +create unique index orders_id_uindex + on orders (id); + +INSERT INTO public.address (id, city, street, house, apartment) VALUES (7, 'г. Тверь', 'ул. 2-я Серова', 33, 33); +INSERT INTO public.address (id, city, street, house, apartment) VALUES (8, 'hfhgdf', 'dg', 1212, 121); + +INSERT INTO public.orders (id, status, address_id, user_id, cart, date) VALUES (1, 'new', 7, 3, '[{"id": 9, "price": 123, "title": "Латук", "categoryDto": [1]}, {"id": 22, "price": 2324, "title": "Абрикос", "categoryDto": [2]}]', '2021-10-12'); +INSERT INTO public.orders (id, status, address_id, user_id, cart, date) VALUES (2, 'new', 8, 3, '[{"id": 22, "price": 2324, "title": "Абрикос", "categoryDto": [2]}, {"id": 6, "price": 180, "title": "Виноград", "categoryDto": [2]}]', '2021-10-12'); + diff --git a/src/main/resources/db/migration/V1_produc_and_category_create_table.sql b/src/main/resources/db/migration/V1_produc_and_category_create_table.sql index 2b09450..3d66c83 100644 --- a/src/main/resources/db/migration/V1_produc_and_category_create_table.sql +++ b/src/main/resources/db/migration/V1_produc_and_category_create_table.sql @@ -26,4 +26,31 @@ CREATE TABLE IF NOT EXISTS product_category primary key (product_id, category_id), foreign key (product_id) references product (id), foreign key (category_id) references category (id) -) +); + +INSERT INTO public.category (id, title, parent_id) VALUES (1, 'Овощи', null); +INSERT INTO public.category (id, title, parent_id) VALUES (2, 'Фрукты', null); +INSERT INTO public.category (id, title, parent_id) VALUES (3, 'Рыба с/с', null); +INSERT INTO public.category (id, title, parent_id) VALUES (4, 'Колбасы с/к', null); + +INSERT INTO public.product (id, title, price, image) VALUES (5, 'Фейхоа', 180, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (6, 'Виноград', 180, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (8, 'Перец красный', 189, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (9, 'Латук', 123, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (12, 'Томаты', 232, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (14, 'Абрикос', 232, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (15, 'Персики', 232, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (17, 'Шампиньоны', 212, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (18, 'Огурцы', 343, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); +INSERT INTO public.product (id, title, price, image) VALUES (19, 'Лосось с/с', 1500, '\data\images\product\e495ff3eb9c55bd0bcdde0f468b679f4.jpg'); + +INSERT INTO public.product_category (product_id, category_id) VALUES (5, 2); +INSERT INTO public.product_category (product_id, category_id) VALUES (6, 2); +INSERT INTO public.product_category (product_id, category_id) VALUES (8, 1); +INSERT INTO public.product_category (product_id, category_id) VALUES (9, 1); +INSERT INTO public.product_category (product_id, category_id) VALUES (12, 1); +INSERT INTO public.product_category (product_id, category_id) VALUES (14, 2); +INSERT INTO public.product_category (product_id, category_id) VALUES (15, 2); +INSERT INTO public.product_category (product_id, category_id) VALUES (17, 1); +INSERT INTO public.product_category (product_id, category_id) VALUES (18, 1); +INSERT INTO public.product_category (product_id, category_id) VALUES (19, 3); diff --git a/src/main/resources/db/migration/V1_user_and_role_create_table.sql b/src/main/resources/db/migration/V1_user_and_role_create_table.sql new file mode 100644 index 0000000..bd026f4 --- /dev/null +++ b/src/main/resources/db/migration/V1_user_and_role_create_table.sql @@ -0,0 +1,39 @@ +create table users +( + id bigserial, + username varchar(30) not null unique, + password varchar(80) not null, + email varchar(50) unique, + enabled boolean default true, + primary key (id) +); + +create table role +( + id serial, + name varchar(50) not null, + primary key (id) +); + +CREATE TABLE user_role +( + user_id bigint not null, + role_id int not null, + primary key (user_id, role_id), + foreign key (user_id) references users (id), + foreign key (role_id) references role (id) +); + +insert into role (name) +values ('ROLE_USER'), + ('ROLE_MANAGER'), + ('ROLE_ADMIN'); + +INSERT INTO public.users (id, username, password, email, enabled) VALUES (2, 'ggg', '$2a$08$2RO4rUMaLLW4z4aFpSqchelNnPgJp4T/1OAvEvALpkDbQvD7eavxe', 'ggg@ggg', true); +INSERT INTO public.users (id, username, password, email, enabled) VALUES (3, 'fff', '$2a$08$JYwknbmooZXl5a.Yb8ABbeNGMX/sKyIe0PgvwN9fYilcYeGzPLLD.', 'fff@fff', true); +INSERT INTO public.users (id, username, password, email, enabled) VALUES (5, 'rrr', '$2a$08$OstLi7a0.S0FC1nERZsC8uuU0pbGQPWRVmkel.DFaNWUcm08KeWOy', 'rrr@rrr', true); + +INSERT INTO public.user_role (user_id, role_id) VALUES (2, 3); +INSERT INTO public.user_role (user_id, role_id) VALUES (3, 1); +INSERT INTO public.user_role (user_id, role_id) VALUES (5, 1); + diff --git a/src/main/resources/templates/cart/list.html b/src/main/resources/templates/cart/list.html index 3f48037..aceeaa4 100644 --- a/src/main/resources/templates/cart/list.html +++ b/src/main/resources/templates/cart/list.html @@ -47,6 +47,8 @@ Сумма: + Создать заказ + diff --git a/src/main/resources/templates/category/form.html b/src/main/resources/templates/category/form.html index 2768f44..7567887 100644 --- a/src/main/resources/templates/category/form.html +++ b/src/main/resources/templates/category/form.html @@ -12,9 +12,9 @@

Добавить категорию

-

+

diff --git a/src/main/resources/templates/category/list.html b/src/main/resources/templates/category/list.html index 8a0ca8f..0b12cf0 100644 --- a/src/main/resources/templates/category/list.html +++ b/src/main/resources/templates/category/list.html @@ -9,16 +9,14 @@
Header
-
filter
Card title
+ К продуктам
- -
Footer
diff --git a/src/main/resources/templates/filter/filter.html b/src/main/resources/templates/filter/filter.html deleted file mode 100644 index 44c1709..0000000 --- a/src/main/resources/templates/filter/filter.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - filter - - - - - - \ No newline at end of file diff --git a/src/main/resources/templates/fragment/header.html b/src/main/resources/templates/fragment/header.html index 7c9f96c..6d0e0c1 100644 --- a/src/main/resources/templates/fragment/header.html +++ b/src/main/resources/templates/fragment/header.html @@ -1,5 +1,5 @@ - + @@ -9,13 +9,14 @@ + +
diff --git a/src/main/resources/templates/order/list.html b/src/main/resources/templates/order/list.html new file mode 100644 index 0000000..036155b --- /dev/null +++ b/src/main/resources/templates/order/list.html @@ -0,0 +1,50 @@ + + + + + list order + + + +
Header
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#СтатусАдресДата заказаСписок покупок
+
+
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/order/newOrder.html b/src/main/resources/templates/order/newOrder.html new file mode 100644 index 0000000..35f1c29 --- /dev/null +++ b/src/main/resources/templates/order/newOrder.html @@ -0,0 +1,82 @@ + + + + + Add order + + + +
Header
+ +
+ +
+
+ + + + + + + + + + + + + + + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+ + + + + + + + + + + +
+ + + + + + + + + + + + + + +
+ +
+ +
+
+ + + \ No newline at end of file diff --git a/src/main/resources/templates/product/form.html b/src/main/resources/templates/product/form.html index d685026..f28feb1 100644 --- a/src/main/resources/templates/product/form.html +++ b/src/main/resources/templates/product/form.html @@ -12,7 +12,7 @@

Добавление/Редактирование продукта

- +

@@ -22,13 +22,12 @@

- +

- - +
diff --git a/src/main/resources/templates/product/list.html b/src/main/resources/templates/product/list.html index 3be5d00..5f7214b 100644 --- a/src/main/resources/templates/product/list.html +++ b/src/main/resources/templates/product/list.html @@ -1,5 +1,5 @@ - + Продукты @@ -10,6 +10,7 @@
Header
filter
+
Card title

Cost

Редактировать + th:href="@{/product/form(id=${product.id})}" sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER')">Редактировать Удалить + th:href="@{/product/delete(id=${product.id})}" sec:authorize="hasAnyRole('ROLE_ADMIN', 'ROLE_MANAGER')">Удалить
diff --git a/src/main/resources/templates/user/admin.html b/src/main/resources/templates/user/admin.html new file mode 100644 index 0000000..6ae7c67 --- /dev/null +++ b/src/main/resources/templates/user/admin.html @@ -0,0 +1,47 @@ + + + + + Пользователи + + + +
Header
+
+ +

Пользователи

+ +
+ + + + + + + + + + + + + + + + +
#ЛогинEmailРоли
+ + + + + Заблокировать + Активировать +
+
+ +
+ Footer +
+
+ + \ No newline at end of file diff --git a/src/main/resources/templates/user/personalAccount.html b/src/main/resources/templates/user/personalAccount.html new file mode 100644 index 0000000..81cdec0 --- /dev/null +++ b/src/main/resources/templates/user/personalAccount.html @@ -0,0 +1,42 @@ + + + + + personal account + + + +
Header
+
+
+
+ +
+ +
+
+ + + + + + + + + + + + + + + + +
Имяemail
+
+
+
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/user/registration.html b/src/main/resources/templates/user/registration.html new file mode 100644 index 0000000..39671d9 --- /dev/null +++ b/src/main/resources/templates/user/registration.html @@ -0,0 +1,56 @@ + + + + + Пользователи + + + +
Header
+
+ +
+
+
+
+
+ + + + +
Регистрация
+ +
+ + +
+ +
+ + +
+
+ + +
+ + + +
+ Уже зарегистрированы? + Войти +
+
+
+
+
+
+ +
+ Footer +
+
+ + + \ No newline at end of file diff --git a/src/test/java/com/example/springmvc/controller/ProductControllerTest.java b/src/test/java/com/example/springmvc/mvcLayer/controller/ProductControllerTest.java similarity index 94% rename from src/test/java/com/example/springmvc/controller/ProductControllerTest.java rename to src/test/java/com/example/springmvc/mvcLayer/controller/ProductControllerTest.java index 41ca301..a527d2a 100644 --- a/src/test/java/com/example/springmvc/controller/ProductControllerTest.java +++ b/src/test/java/com/example/springmvc/mvcLayer/controller/ProductControllerTest.java @@ -1,9 +1,6 @@ -package com.example.springmvc.controller; +package com.example.springmvc.mvcLayer.controller; -import com.example.springmvc.SpringMvcApplicationTests; -import com.example.springmvc.domain.Category; -import com.example.springmvc.domain.Product; -//import com.example.springmvc.service.ProductService; +//import com.example.springmvc.mvcLayer.service.ProductService; //import org.junit.jupiter.api.BeforeEach; //import org.junit.jupiter.api.Test; //import org.mockito.Mockito;