немного визуала и логики
This commit is contained in:
parent
2a90a06662
commit
61ba8d8066
BIN
data.mv.db
BIN
data.mv.db
Binary file not shown.
@ -55,13 +55,15 @@ public class DemoApplication implements CommandLineRunner {
|
||||
admin.setRole(UserRole.ADMIN);
|
||||
userService.create(admin);
|
||||
final var user1 = userService.create(new UserEntity("user", "user@gmail.com",
|
||||
Constants.DEFAULT_PASSWORD));
|
||||
Constants.DEFAULT_PASSWORD));
|
||||
|
||||
final var type1 = typeService.create(new TypeEntity("ААА"));
|
||||
final var type2 = typeService.create(new TypeEntity("АА"));
|
||||
|
||||
final var genre1 = genreService.create(new GenreEntity("Приключения"));
|
||||
final var genre2 = genreService.create(new GenreEntity("Симулятор"));
|
||||
final var genre3 = genreService.create(new GenreEntity("Выживание"));
|
||||
final var genre4 = genreService.create(new GenreEntity("Рогалик"));
|
||||
|
||||
final List<GenreEntity> genres1 = new ArrayList<GenreEntity>();
|
||||
genres1.add(genre1);
|
||||
@ -70,10 +72,17 @@ public class DemoApplication implements CommandLineRunner {
|
||||
final List<GenreEntity> genres2 = new ArrayList<GenreEntity>();
|
||||
genres2.add(genre2);
|
||||
|
||||
final var game1 = gameService.create(new GameEntity(type1, "Game1", 2100.0,
|
||||
"good game", genres1));
|
||||
final var game2 = gameService.create(new GameEntity(type2, "Game2", 1200.0,
|
||||
"bad game", genres2));
|
||||
final List<GenreEntity> genres3 = new ArrayList<GenreEntity>();
|
||||
genres3.add(genre3);
|
||||
genres3.add(genre4);
|
||||
|
||||
final var game1 = gameService.create(new GameEntity(type1, "Game1", 2100.0, "good game", genres3));
|
||||
final var game2 = gameService.create(new GameEntity(type2, "Game2", 1200.0, "bad game", genres2));
|
||||
gameService.create(new GameEntity(type1, "Game3", 500.0, "game3", genres2));
|
||||
gameService.create(new GameEntity(type2, "Game4", 3200.0, "game4", genres3));
|
||||
gameService.create(new GameEntity(type1, "Game5", 1200.0, "game", genres2));
|
||||
gameService.create(new GameEntity(type2, "Game6", 1200.0, "norm game", genres2));
|
||||
gameService.create(new GameEntity(type1, "Game7", 1200.0, "game", genres3));
|
||||
final List<GameEntity> games = new ArrayList<GameEntity>();
|
||||
games.add(game1);
|
||||
games.add(game2);
|
||||
|
@ -18,46 +18,54 @@ public interface GameRepository extends CrudRepository<GameEntity, Long>, Paging
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres ge join fetch g.type ty where ge.id = ?2 and ty.id = ?1")
|
||||
Page<GameEntity> findByTypeIdAndGenres(long typeId, long genreId, Pageable pageable);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres ge join fetch g.type ty where ge.id = ?2 and ty.id = ?1")
|
||||
List<GameEntity> findByTypeIdAndGenres(long typeId, long genreId);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.type ty where ty.id = ?1")
|
||||
@Query("select distinct g from GameEntity g join fetch g.type ty join fetch g.genres ge where ty.id = ?1")
|
||||
Page<GameEntity> findByTypeId(long typeId, Pageable pageable);
|
||||
@Query("select distinct g from GameEntity g join fetch g.type ty where ty.id = ?1")
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.type ty join fetch g.genres ge where ty.id = ?1")
|
||||
List<GameEntity> findByTypeId(long typeId);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres ge where ge.id = ?1")
|
||||
Page<GameEntity> findByGenres(long genre, Pageable pageable);
|
||||
Page<GameEntity> findByGenreId(long genre, Pageable pageable);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres ge where ge.id = ?1")
|
||||
List<GameEntity> findByGenres(long genre);
|
||||
List<GameEntity> findByGenreId(long genre);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres join fetch g.type ty")
|
||||
Page<GameEntity>findAll(Pageable pageable);
|
||||
Page<GameEntity> findAll(Pageable pageable);
|
||||
|
||||
@Query("select distinct g from GameEntity g join fetch g.genres join fetch g.type ty")
|
||||
List<GameEntity>findAll();
|
||||
List<GameEntity> findAll();
|
||||
|
||||
}
|
||||
|
||||
/* "select "
|
||||
+ "ga.id, ga.description, ga.name, ga.price, ga.type_id "
|
||||
+ "from games ga left join fetch games_genres g on ga.id = g.game_entity_id "
|
||||
+ "where g.id = ?1 "
|
||||
+ "order by ga.id"*/
|
||||
/*
|
||||
* "select "
|
||||
* + "ga.id, ga.description, ga.name, ga.price, ga.type_id "
|
||||
* + "from games ga left join fetch games_genres g on ga.id = g.game_entity_id "
|
||||
* + "where g.id = ?1 "
|
||||
* + "order by ga.id"
|
||||
*/
|
||||
|
||||
//select ge1_0.id,ge1_0.name from genres ge1_0 where ge1_0.id=?
|
||||
// select ge1_0.id,ge1_0.name from genres ge1_0 where ge1_0.id=?
|
||||
|
||||
//select ge1_0.id,ge1_0.description,ge1_0.name,ge1_0.price,ge1_0.type_id
|
||||
//from games ge1_0 left join games_genres g1_0 on ge1_0.id=g1_0.game_entity_id
|
||||
//where g1_0.genres_id=? offset ? rows fetch first ? rows only
|
||||
// select ge1_0.id,ge1_0.description,ge1_0.name,ge1_0.price,ge1_0.type_id
|
||||
// from games ge1_0 left join games_genres g1_0 on ge1_0.id=g1_0.game_entity_id
|
||||
// where g1_0.genres_id=? offset ? rows fetch first ? rows only
|
||||
|
||||
//select te1_0.id,te1_0.name from types te1_0 where te1_0.id=?
|
||||
// select te1_0.id,te1_0.name from types te1_0 where te1_0.id=?
|
||||
|
||||
//select g1_0.game_entity_id,g1_1.id,g1_1.name from games_genres g1_0 join genres g1_1 on g1_1.id=g1_0.genres_id where g1_0.game_entity_id=?
|
||||
// select g1_0.game_entity_id,g1_1.id,g1_1.name from games_genres g1_0 join
|
||||
// genres g1_1 on g1_1.id=g1_0.genres_id where g1_0.game_entity_id=?
|
||||
|
||||
// @Query("select "
|
||||
// + "t as type, "
|
||||
// + "coalesce(sum(o.price), 0) as totalPrice, "
|
||||
// + "coalesce(sum(o.count), 0) as totalCount "
|
||||
// + "from TypeEntity t left join OrderEntity o on o.type = t and o.user.id = ?1 "
|
||||
// + "from TypeEntity t left join OrderEntity o on o.type = t and o.user.id = ?1
|
||||
// "
|
||||
// + "group by t order by t.id")
|
||||
// List<OrderGrouped> getOrdersTotalByType(long userId);
|
||||
|
@ -32,7 +32,7 @@ public class GameService {
|
||||
return repository.findByTypeIdAndGenres(typeId, genre);
|
||||
}
|
||||
if (Objects.equals(typeId, 0L) && !Objects.equals(genre, 0L)) {
|
||||
return repository.findByGenres(genre);
|
||||
return repository.findByGenreId(genre);
|
||||
}
|
||||
if (!Objects.equals(typeId, 0L) && Objects.equals(genre, 0L)) {
|
||||
return repository.findByTypeId(typeId);
|
||||
@ -48,7 +48,7 @@ public class GameService {
|
||||
return repository.findByTypeIdAndGenres(typeId, genre, pageRequest);
|
||||
}
|
||||
if (Objects.equals(typeId, 0L) && !Objects.equals(genre, 0L)) {
|
||||
return repository.findByGenres(genre, pageRequest);
|
||||
return repository.findByGenreId(genre, pageRequest);
|
||||
}
|
||||
if (!Objects.equals(typeId, 0L) && Objects.equals(genre, 0L)) {
|
||||
return repository.findByTypeId(typeId, pageRequest);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.example.demo.users.api;
|
||||
|
||||
import org.springframework.security.core.annotation.AuthenticationPrincipal;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
@ -11,12 +10,20 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.support.SessionStatus;
|
||||
|
||||
import org.modelmapper.ModelMapper;
|
||||
|
||||
import com.example.demo.core.api.PageAttributesMapper;
|
||||
import com.example.demo.core.configuration.Constants;
|
||||
import com.example.demo.core.session.SessionCart;
|
||||
import com.example.demo.games.api.GameDto;
|
||||
import com.example.demo.games.model.GameEntity;
|
||||
import com.example.demo.games.service.GameService;
|
||||
import com.example.demo.genres.api.GenreDto;
|
||||
import com.example.demo.genres.model.GenreEntity;
|
||||
import com.example.demo.genres.service.GenreService;
|
||||
import com.example.demo.types.api.TypeDto;
|
||||
import com.example.demo.types.model.TypeEntity;
|
||||
import com.example.demo.types.service.TypeService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
@ -25,17 +32,24 @@ import jakarta.validation.Valid;
|
||||
public class UserCatalogController {
|
||||
|
||||
private static final String CATALOG_VIEW = "catalog";
|
||||
public static final String URL = "/catalog";
|
||||
public static final String URL = "/catalog";
|
||||
private static final String TYPEID_ATTRIBUTE = "typeId";
|
||||
private static final String GENREID_ATTRIBUTE = "genreId";
|
||||
private static final String PAGE_ATTRIBUTE = "page";
|
||||
private static final String ORDER_ATTRIBUTE = "order";
|
||||
private static final String CART_ATTRIBUTE = "cart";
|
||||
|
||||
|
||||
private final GameService gameService;
|
||||
private final GenreService genreService;
|
||||
private final TypeService typeService;
|
||||
private final ModelMapper modelMapper;
|
||||
private final SessionCart cart;
|
||||
|
||||
public UserCatalogController(GameService gameService, SessionCart cart){
|
||||
public UserCatalogController(GameService gameService, SessionCart cart, GenreService genreService,
|
||||
TypeService typeService, ModelMapper modelMapper) {
|
||||
this.gameService = gameService;
|
||||
this.modelMapper = modelMapper;
|
||||
this.genreService = genreService;
|
||||
this.typeService = typeService;
|
||||
this.cart = cart;
|
||||
}
|
||||
|
||||
@ -50,19 +64,34 @@ public class UserCatalogController {
|
||||
return dto;
|
||||
}
|
||||
|
||||
private GenreDto toGenreDto(GenreEntity entity) {
|
||||
return modelMapper.map(entity, GenreDto.class);
|
||||
}
|
||||
|
||||
private TypeDto toTypeDto(TypeEntity entity) {
|
||||
return modelMapper.map(entity, TypeDto.class);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public String getCatalog(
|
||||
@RequestParam(name = PAGE_ATTRIBUTE, defaultValue = "0") int page,
|
||||
@RequestParam(name = TYPEID_ATTRIBUTE, defaultValue = "0") int typeId,
|
||||
@RequestParam(name = GENREID_ATTRIBUTE, defaultValue = "0") int genreId,
|
||||
Model model) {
|
||||
model.addAttribute(ORDER_ATTRIBUTE, new UserCartDto());
|
||||
model.addAttribute(PAGE_ATTRIBUTE, page);
|
||||
model.addAttribute("games",
|
||||
gameService.getAll(0, 0).stream()
|
||||
.map(this::toGameDto)
|
||||
model.addAllAttributes(PageAttributesMapper.toAttributes(
|
||||
gameService.getAll(typeId, genreId, page, Constants.DEFAULT_PAGE_SIZE), this::toGameDto));
|
||||
model.addAttribute("genres",
|
||||
genreService.getAll().stream()
|
||||
.map(this::toGenreDto)
|
||||
.toList());
|
||||
model.addAttribute("types",
|
||||
typeService.getAll().stream()
|
||||
.map(this::toTypeDto)
|
||||
.toList());
|
||||
return CATALOG_VIEW;
|
||||
}
|
||||
///catalog/addCart/{id}
|
||||
|
||||
@PostMapping
|
||||
public String addOrderToCart(
|
||||
|
@ -22,6 +22,10 @@ td form {
|
||||
margin-top: -.25em;
|
||||
}
|
||||
|
||||
.main {
|
||||
background-color: #353b47;
|
||||
}
|
||||
|
||||
.button-fixed-width {
|
||||
width: 150px;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content" class="w-50 mx-auto">
|
||||
<main layout:fragment="content" class="w-50 mx-auto py-3">
|
||||
<div class="d-flex flex-column align-items-center">
|
||||
<div class="mb-2 col-12 col-md-8 col-lg-6 d-flex align-items-center">
|
||||
<strong class="flex-fill">Корзина</strong>
|
||||
@ -19,11 +19,11 @@
|
||||
</div>
|
||||
<div class="card col-12 col-md-8 col-lg-6 w-75 align-items-center" th:each="cartItem : ${cart}">
|
||||
<div class="card-body col-12 p-2 d-flex flex-row align-items-center justify-content-center">
|
||||
<div class="col-5">
|
||||
<div class="col-5"><img src="/risk-of-rain-returns.jpg" class="w-75"></div>
|
||||
<div class="col-3">
|
||||
Название: [[${cartItem.gameName}]]
|
||||
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="col-4">
|
||||
Цена: [[${cartItem.Price}]]
|
||||
</div>
|
||||
</div>
|
||||
@ -40,7 +40,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<div class="mb-2 p-2">
|
||||
<form action=" #" th:action="@{/cart}" th:object="${order}" method="post">
|
||||
<div class="mb-2">
|
||||
<label for="game" class="form-label">Товары</label>
|
||||
|
@ -6,48 +6,90 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content" class="w-50 mx-auto">
|
||||
<main layout:fragment="content" class="w-50 mx-auto main">
|
||||
<div class="tab-content mt-2">
|
||||
<h2 class="text-center">Игры</h2>
|
||||
<div className="row mx-auto">
|
||||
<div className="img pt-4 ps-5 mt-4 col-8">
|
||||
<img className="img" src="/risk-of-rain-returns.jpg" width="100%" />
|
||||
<div class="row mx-auto">
|
||||
<div class=" pt-4 mt-4 col-8">
|
||||
<img class="m-2" src="/risk-of-rain-returns.jpg" width="95%" />
|
||||
</div>
|
||||
<div className="pe-3 flex-column div col-4">
|
||||
<div className="pt-4 ps-2">Популярные новинки:</div>
|
||||
<div><img className="p-2" src="/risk-of-rain-returns.jpg" width="100%" /></div>
|
||||
<div><img className="p-2" src="/risk-of-rain-returns.jpg" width="100%" /></div>
|
||||
<div class="pe-3 flex-column div col-4">
|
||||
<div class="pt-4 ps-2">Популярные новинки:</div>
|
||||
<div><img class="p-2" src="/risk-of-rain-returns.jpg" width="100%" /></div>
|
||||
<div><img class="p-2" src="/risk-of-rain-returns.jpg" width="100%" /></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tab-pane container active table-responsive" id="orders">
|
||||
<form th:action="@{/catalog}" method="get" class="row mt-2 w-50 mx-auto pb-3">
|
||||
<div class="pb-3">
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<select th:name="typeId" id="typeId" class="form-select">
|
||||
<option selected value="">Фильтр по типу</option>
|
||||
<option th:each="type : ${types}" th:value="${type.id}" th:selected="${type.id==typeId}">
|
||||
[[${type.name}]]
|
||||
</option>
|
||||
</select>
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<select th:name="genreId" id="genreId" class="form-select">
|
||||
<option selected value="">Фильтр по жанру</option>
|
||||
<option th:each="genre : ${genres}" th:value="${genre.id}"
|
||||
th:selected="${genre.id==genreId}">
|
||||
[[${genre.name}]]
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Показать</button>
|
||||
</form>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th class="w-25"></th>
|
||||
<th>Название</th>
|
||||
<th>Тип</th>
|
||||
<th>Жанры</th>
|
||||
<th class="w-auto">Описание</th>
|
||||
<th>Цена</th>
|
||||
<th>Цена</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="gamee : ${games}">
|
||||
<tr th:each="gamee : ${items}">
|
||||
<th scope="row"><img src="/risk-of-rain-returns.jpg" class="w-100"></th>
|
||||
<th scope="row" th:text="${gamee.name}"></th>
|
||||
<th:block th:each="type : ${types}">
|
||||
<th:block th:if="${type.Id} eq ${gamee.typeId}">
|
||||
<th scope="row" th:text="${type.name}"></th>
|
||||
</th:block>
|
||||
</th:block>
|
||||
<th scope="row">
|
||||
<th:block th:each="genre : ${genres}">
|
||||
<th:block th:each="ggenre : ${gamee.genres}">
|
||||
<th:block th:if="${genre.Id} eq ${ggenre}">
|
||||
[[${genre.name}]]<br />
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th:block>
|
||||
</th>
|
||||
<th scope="row" th:text="${gamee.description}"></th>
|
||||
<th scope="row" th:text="${gamee.Price}"></th>
|
||||
<th>
|
||||
<form th:action="@{/catalog}" th:object="${order}" method="post">
|
||||
<input type="hidden" th:name="page" th:value="${page}">
|
||||
<select hidden="hidden" th:field="*{game}" class="form-select">
|
||||
<option th:value="${gamee.id}"></option>
|
||||
</select>
|
||||
<button type="submit" class="btn btn-link button-link"><i class="bi bi-cart2 d-inline-block align-top me-1 logo"></i></button>
|
||||
<button type="submit" class="btn btn-link button-link"><i
|
||||
class="bi bi-cart2 d-inline-block align-top me-1 logo"></i></button>
|
||||
</form>
|
||||
</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<th:block th:replace="~{ pagination :: pagination (
|
||||
url='catalog',
|
||||
totalPages=${totalPages},
|
||||
currentPage=${currentPage}) }" />
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
@ -25,6 +25,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="w-10"></th>
|
||||
<th scope="col" class="w-25"></th>
|
||||
<th scope="col" class="w-auto">Название игры</th>
|
||||
<th scope="col" class="w-10">Цена</th>
|
||||
</tr>
|
||||
@ -34,6 +35,8 @@
|
||||
<th:block th:each="game : ${games}">
|
||||
<th:block th:if="${gameId} eq ${game.id}">
|
||||
<th scope="row" th:text="${gameId}"></th>
|
||||
<th scope="row"><img src="/risk-of-rain-returns.jpg" class="w-100">
|
||||
</th>
|
||||
<th scope="row" th:text="${game.name}"></th>
|
||||
<th scope="row" th:text="${game.price}"></th>
|
||||
</th:block>
|
||||
@ -57,7 +60,7 @@
|
||||
url='',
|
||||
totalPages=${totalPages},
|
||||
currentPage=${currentPage}) }" />
|
||||
<div class="mt-2 d-flex justify-content-center">
|
||||
<div class="mb-2 d-flex justify-content-center">
|
||||
<a class="btn btn-primary" href="/cart">Создать заказ</a>
|
||||
</div>
|
||||
</th:block>
|
||||
|
@ -6,7 +6,7 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<main layout:fragment="content" class="w-50 mx-auto">
|
||||
<main layout:fragment="content" class="w-50 mx-auto main">
|
||||
<!-- <ul class="nav nav-pills justify-content-center" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="pill" href="#orders">Заказы</a>
|
||||
|
Loading…
Reference in New Issue
Block a user