немного визуала и логики

This commit is contained in:
Максим Яковлев 2024-05-16 21:48:20 +04:00
parent 2a90a06662
commit 61ba8d8066
10 changed files with 149 additions and 54 deletions

Binary file not shown.

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -22,6 +22,10 @@ td form {
margin-top: -.25em;
}
.main {
background-color: #353b47;
}
.button-fixed-width {
width: 150px;
}

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>