добавлена работа со списками продуктов, попытка оптимизировать запрос по поиску коктейлей
This commit is contained in:
@@ -12,6 +12,7 @@ import {MenuPage} from "./pages/cocktails/MenuPage";
|
|||||||
import {EditIngredientPage} from "./pages/ingredients/EditIngredientPage";
|
import {EditIngredientPage} from "./pages/ingredients/EditIngredientPage";
|
||||||
import {EditCocktailPage} from "./pages/cocktails/EditCocktailPage";
|
import {EditCocktailPage} from "./pages/cocktails/EditCocktailPage";
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
|
import {BarChangePage} from "./pages/BarChangePage";
|
||||||
|
|
||||||
export function NavigationRoutes() {
|
export function NavigationRoutes() {
|
||||||
const {auth} = useAuth();
|
const {auth} = useAuth();
|
||||||
@@ -64,6 +65,11 @@ const authPages = [
|
|||||||
children: (<MenuPage/>),
|
children: (<MenuPage/>),
|
||||||
exact: true,
|
exact: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: paths.bar.list,
|
||||||
|
isPrivate: true,
|
||||||
|
children: (<BarChangePage/>),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: paths.bar.ingredients,
|
path: paths.bar.ingredients,
|
||||||
isPrivate: true,
|
isPrivate: true,
|
||||||
|
|||||||
111
front/src/app/pages/BarChangePage.js
Normal file
111
front/src/app/pages/BarChangePage.js
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
import Paper from "@mui/material/Paper";
|
||||||
|
import React, {useEffect, useState} from "react";
|
||||||
|
import {api} from "../../lib/clients/api";
|
||||||
|
import {requests} from "../../requests";
|
||||||
|
import {useAlert} from "../../hooks/useAlert";
|
||||||
|
import {Card} from "@mui/material";
|
||||||
|
import Stack from "@mui/material/Stack";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import IconButton from "@mui/material/IconButton";
|
||||||
|
import Box from "@mui/material/Box";
|
||||||
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
|
import ElectricalServicesIcon from '@mui/icons-material/ElectricalServices';
|
||||||
|
import {getComparator} from "../../components/core/getComparator";
|
||||||
|
import Toolbar from "@mui/material/Toolbar";
|
||||||
|
import AddCircleIcon from '@mui/icons-material/AddCircle';
|
||||||
|
import {BarCreateModal} from "../../components/BarCreateModal";
|
||||||
|
import PowerIcon from '@mui/icons-material/Power';
|
||||||
|
|
||||||
|
export function BarChangePage() {
|
||||||
|
const [bars, setBars] = useState([])
|
||||||
|
const [open, setOpen] = useState(false)
|
||||||
|
const {createError, createSuccess, createWarning} = useAlert();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
api().get(requests.bar.list)
|
||||||
|
.then((r) => {
|
||||||
|
setBars(r.data.sort(getComparator("name")))
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
createError("Ошибка получения списков")
|
||||||
|
})
|
||||||
|
}, []);
|
||||||
|
const changeHandler = (bar) => {
|
||||||
|
createWarning("Дождитесь окончания операции")
|
||||||
|
api().post(`${requests.bar.change}/${bar.id}`)
|
||||||
|
.then(() => createSuccess("Список изменен"))
|
||||||
|
.catch(() => createError("Ошибка изменения активного списка"))
|
||||||
|
|
||||||
|
const newState = bars.map((b) => {
|
||||||
|
if (b.active) {
|
||||||
|
return {
|
||||||
|
...b, active: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (b.id === bar.id) {
|
||||||
|
return {
|
||||||
|
...b, active: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
})
|
||||||
|
setBars(newState);
|
||||||
|
}
|
||||||
|
const deleteHandler = (bar) => {
|
||||||
|
if (bar.active) {
|
||||||
|
createError("Нельзя удалить активный бар!")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
api().delete(requests.bar.crud + bar.id)
|
||||||
|
.then(() => createSuccess("Список удален"))
|
||||||
|
.catch(() => createError("Ошибка удаления. Обновите страницу"))
|
||||||
|
|
||||||
|
setBars(bars.filter((b) => b.id !== bar.id));
|
||||||
|
}
|
||||||
|
const createHandler = (name) => {
|
||||||
|
api().post(requests.bar.crud + name)
|
||||||
|
.then((r) => {
|
||||||
|
createSuccess("Cписок создан");
|
||||||
|
let state = bars;
|
||||||
|
state.push(r.data);
|
||||||
|
setBars(state)
|
||||||
|
setOpen(false)
|
||||||
|
}).catch(() => createError("Ошибка создания списка"))
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeHandler() {
|
||||||
|
setOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<BarCreateModal open={open} close={closeHandler} create={createHandler}/>
|
||||||
|
<Paper sx={{p: 1}}>
|
||||||
|
<Toolbar>
|
||||||
|
<Typography variant='h6'>Списки ингредиентов (бары)</Typography>
|
||||||
|
<IconButton edge="end" onClick={() => setOpen(true)}>
|
||||||
|
<AddCircleIcon/>
|
||||||
|
</IconButton>
|
||||||
|
</Toolbar>
|
||||||
|
{bars.map((b) => {
|
||||||
|
return <Card key={b.id} sx={{m: 2, p: 2}}>
|
||||||
|
<Stack direction='row' justifyContent={'space-between'}>
|
||||||
|
<Typography>{b.name}</Typography>
|
||||||
|
{b.active && <IconButton disabled>
|
||||||
|
<PowerIcon/>
|
||||||
|
</IconButton>}
|
||||||
|
{!b.active && <Box>
|
||||||
|
<IconButton onClick={() => deleteHandler(b)}>
|
||||||
|
<DeleteIcon/>
|
||||||
|
</IconButton>
|
||||||
|
<IconButton onClick={() => changeHandler(b)}>
|
||||||
|
<ElectricalServicesIcon/>
|
||||||
|
</IconButton>
|
||||||
|
</Box>}
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
})}
|
||||||
|
</Paper>
|
||||||
|
</>
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
39
front/src/components/BarCreateModal.js
Normal file
39
front/src/components/BarCreateModal.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import Dialog from "@mui/material/Dialog";
|
||||||
|
import DialogTitle from "@mui/material/DialogTitle";
|
||||||
|
import * as React from "react";
|
||||||
|
import Typography from "@mui/material/Typography";
|
||||||
|
import DialogContent from "@mui/material/DialogContent";
|
||||||
|
import DialogActions from "@mui/material/DialogActions";
|
||||||
|
import Button from "@mui/material/Button";
|
||||||
|
import {useState} from "react";
|
||||||
|
import TextField from "@mui/material/TextField";
|
||||||
|
|
||||||
|
export function BarCreateModal({open, close, create}) {
|
||||||
|
const [value, setValue] = useState("");
|
||||||
|
return (
|
||||||
|
<Dialog fullWidth={true}
|
||||||
|
open={open} onClose={close}
|
||||||
|
sx={{
|
||||||
|
'& .MuiDialog-paper': {
|
||||||
|
margin: '8px',
|
||||||
|
},
|
||||||
|
'& .MuiPaper-root': {
|
||||||
|
width: 'calc(100% - 16px)',
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<DialogTitle>
|
||||||
|
<Typography>Создать список</Typography>
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogContent>
|
||||||
|
<TextField sx={{width: '75%'}}
|
||||||
|
label={"Название списка"} variant='outlined'
|
||||||
|
value={!value ? "" : value}
|
||||||
|
onChange={(e) => setValue(e.target.value)}
|
||||||
|
/>
|
||||||
|
</DialogContent>
|
||||||
|
<DialogActions>
|
||||||
|
<Button onClick={() => create(value)}>Создать</Button>
|
||||||
|
</DialogActions>
|
||||||
|
</Dialog>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -11,6 +11,7 @@ import EditIcon from '@mui/icons-material/Edit';
|
|||||||
import DeleteIcon from '@mui/icons-material/Delete';
|
import DeleteIcon from '@mui/icons-material/Delete';
|
||||||
import LocalBarIcon from '@mui/icons-material/LocalBar';
|
import LocalBarIcon from '@mui/icons-material/LocalBar';
|
||||||
import {paths} from "../../path";
|
import {paths} from "../../path";
|
||||||
|
import {useAlert} from "../../hooks/useAlert";
|
||||||
|
|
||||||
function renderFavouriteBadge(handleFavourite, row) {
|
function renderFavouriteBadge(handleFavourite, row) {
|
||||||
const childIcon = row.rating.favourite ? <FavoriteIcon/> : <FavoriteBorderIcon/>;
|
const childIcon = row.rating.favourite ? <FavoriteIcon/> : <FavoriteBorderIcon/>;
|
||||||
@@ -33,6 +34,7 @@ function renderRating(handleChangeRating, row) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) {
|
export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect, deleteHandler}) {
|
||||||
|
const {notImplement} = useAlert();
|
||||||
return (
|
return (
|
||||||
<Grid item sx={{pr: 2}}>
|
<Grid item sx={{pr: 2}}>
|
||||||
<CocktailItemStyled>
|
<CocktailItemStyled>
|
||||||
@@ -55,24 +57,23 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
|
|||||||
image={row.image.includes("thecocktaildb") ? (row.image + "/preview") : row.image}
|
image={row.image.includes("thecocktaildb") ? (row.image + "/preview") : row.image}
|
||||||
/>
|
/>
|
||||||
<CardActions>
|
<CardActions>
|
||||||
<IconButton sx={{m: 0}} size='small'>
|
<IconButton sx={{m: 0}} size='small' onClick={() => notImplement()}>
|
||||||
<LocalBarIcon fontSize='small'/>
|
<LocalBarIcon fontSize='small'/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
{renderFavouriteBadge(handleFavourite, row)}
|
{renderFavouriteBadge(handleFavourite, row)}
|
||||||
{renderRating(handleChangeRating, row)}
|
{renderRating(handleChangeRating, row)}
|
||||||
|
|
||||||
<IconButton size={'small'} href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
|
<IconButton size='small' href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
|
||||||
<EditIcon fontSize={'small'}/>
|
<EditIcon fontSize='small'/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<IconButton size={'small'} onClick={() => deleteHandler(row)}>
|
<IconButton size='small' onClick={() => deleteHandler(row)}>
|
||||||
<DeleteIcon fontSize={'small'}/>
|
<DeleteIcon fontSize='small'/>
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</CardActions>
|
</CardActions>
|
||||||
<CardContent sx={{pb: 0, pl: 2, pt: 0}}>
|
<CardContent sx={{pb: 0, pl: 2, pt: 0}}>
|
||||||
<Typography variant="h5" minHeight={'50px'} mt={2}>{row.name} </Typography>
|
<Typography variant="h5" minHeight={'50px'} mt={2}>{row.name} </Typography>
|
||||||
<CocktailDescription row={row}/>
|
<CocktailDescription row={row}/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
</CocktailItemStyled>
|
</CocktailItemStyled>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ export function useAlert() {
|
|||||||
createAlert("Данный функционал пока не реализован", {variant: 'warning'});
|
createAlert("Данный функционал пока не реализован", {variant: 'warning'});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createWarning(message) {
|
||||||
|
createAlert(message, {variant: 'warning'})
|
||||||
|
}
|
||||||
|
|
||||||
function createError(message) {
|
function createError(message) {
|
||||||
createAlert(message, {variant: "error"});
|
createAlert(message, {variant: "error"});
|
||||||
}
|
}
|
||||||
@@ -28,5 +32,5 @@ export function useAlert() {
|
|||||||
createAlert(message, {variant: "success"});
|
createAlert(message, {variant: "success"});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {createAlert, notImplement, createError, getError, createSuccess}
|
return {createAlert, notImplement, createError, getError, createSuccess, createWarning}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,7 @@ import {paths} from "./path";
|
|||||||
|
|
||||||
export const navItems = [
|
export const navItems = [
|
||||||
{key: 'menu', title: 'Меню', href: paths.dashboard.overview, icon: 'menu'},
|
{key: 'menu', title: 'Меню', href: paths.dashboard.overview, icon: 'menu'},
|
||||||
|
{key: 'barList', title: 'Список баров', href: paths.bar.list, icon: 'basket', forBarmen: true},
|
||||||
{key: 'ingredients', title: 'Список ингредиентов', href: paths.bar.ingredients, icon: 'basket', forBarmen: true},
|
{key: 'ingredients', title: 'Список ингредиентов', href: paths.bar.ingredients, icon: 'basket', forBarmen: true},
|
||||||
{key: 'ingredientEdit', title: 'Ингредиенты', href: paths.bar.ingredientEdit, icon: 'ingredients', forAdmin: true},
|
{key: 'ingredientEdit', title: 'Ингредиенты', href: paths.bar.ingredientEdit, icon: 'ingredients', forAdmin: true},
|
||||||
{key: 'cocktailEdit', title: 'Коктейли', href: paths.bar.cocktailEdit, icon: 'cocktail', forAdmin: true}
|
{key: 'cocktailEdit', title: 'Коктейли', href: paths.bar.cocktailEdit, icon: 'cocktail', forAdmin: true}
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ export const requests = {
|
|||||||
invite: routes.visitor + "/invite?"
|
invite: routes.visitor + "/invite?"
|
||||||
},
|
},
|
||||||
bar: {
|
bar: {
|
||||||
list: routes.bar + "list",
|
list: routes.bar + "all",
|
||||||
|
change: routes.bar + "change",
|
||||||
|
crud: routes.bar,
|
||||||
addToMyList: routes.bar + "addToMyList",
|
addToMyList: routes.bar + "addToMyList",
|
||||||
enter: routes.bar + "enter?id=",
|
enter: routes.bar + "enter?id=",
|
||||||
pay: routes.order + "?",
|
pay: routes.order + "?",
|
||||||
|
|||||||
@@ -3,11 +3,15 @@ package ru.kayashov.bar.controller;
|
|||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.CrossOrigin;
|
import org.springframework.web.bind.annotation.CrossOrigin;
|
||||||
|
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
|
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
|
||||||
|
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
|
||||||
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
||||||
import ru.kayashov.bar.model.entity.Category;
|
import ru.kayashov.bar.model.entity.Category;
|
||||||
import ru.kayashov.bar.model.entity.Glass;
|
import ru.kayashov.bar.model.entity.Glass;
|
||||||
@@ -52,6 +56,26 @@ public class BarController {
|
|||||||
return sessionService.getReceiptList(id);
|
return sessionService.getReceiptList(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/change/{id}")
|
||||||
|
public void changeActiveBar(@PathVariable Long id) {
|
||||||
|
sessionService.changeActiveBar(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public void deleteBar(@PathVariable Long id) {
|
||||||
|
sessionService.deleteBar(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{name}")
|
||||||
|
public BarResponseDto createBar(@PathVariable String name) {
|
||||||
|
return sessionService.createBar(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/all")
|
||||||
|
public List<BarResponseDto> getAll() {
|
||||||
|
return sessionService.findAllBar();
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/getMe")
|
@GetMapping("/getMe")
|
||||||
public VisitorResponseDto getMe() {
|
public VisitorResponseDto getMe() {
|
||||||
Visitor visitor = visitorService.getCurrentVisitor();
|
Visitor visitor = visitorService.getCurrentVisitor();
|
||||||
|
|||||||
@@ -2,13 +2,20 @@ package ru.kayashov.bar.controller.dto.bar;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import ru.kayashov.bar.model.entity.BarEntity;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
public class BarResponseDto {
|
public class BarResponseDto {
|
||||||
private Long id;
|
private Long id;
|
||||||
private String name;
|
private String name;
|
||||||
private Boolean open;
|
private Boolean active;
|
||||||
private Boolean enter;
|
|
||||||
private String myRole;
|
public static BarResponseDto mapToDto(BarEntity barEntity) {
|
||||||
|
BarResponseDto barResponseDto = new BarResponseDto();
|
||||||
|
barResponseDto.setId(barEntity.getId());
|
||||||
|
barResponseDto.setName(barEntity.getName());
|
||||||
|
barResponseDto.setActive(barEntity.getActive());
|
||||||
|
return barResponseDto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public class IngredientEntity {
|
|||||||
private String enName;
|
private String enName;
|
||||||
private Boolean alcohol;
|
private Boolean alcohol;
|
||||||
private Integer abv;
|
private Integer abv;
|
||||||
|
private Boolean isHave;
|
||||||
|
|
||||||
@Column(columnDefinition = "text")
|
@Column(columnDefinition = "text")
|
||||||
private String description;
|
private String description;
|
||||||
|
|||||||
@@ -15,14 +15,12 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
|
|||||||
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
|
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
|
||||||
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
||||||
import ru.kayashov.bar.mapper.CocktailMapper;
|
import ru.kayashov.bar.mapper.CocktailMapper;
|
||||||
import ru.kayashov.bar.model.Ingredient;
|
|
||||||
import ru.kayashov.bar.model.entity.Alcoholic;
|
import ru.kayashov.bar.model.entity.Alcoholic;
|
||||||
import ru.kayashov.bar.model.entity.Category;
|
import ru.kayashov.bar.model.entity.Category;
|
||||||
import ru.kayashov.bar.model.entity.CocktailEntity;
|
import ru.kayashov.bar.model.entity.CocktailEntity;
|
||||||
import ru.kayashov.bar.model.entity.Glass;
|
import ru.kayashov.bar.model.entity.Glass;
|
||||||
import ru.kayashov.bar.model.entity.IngredientEntity;
|
import ru.kayashov.bar.model.entity.IngredientEntity;
|
||||||
import ru.kayashov.bar.model.entity.ReceiptEntity;
|
import ru.kayashov.bar.model.entity.ReceiptEntity;
|
||||||
import ru.kayashov.bar.model.entity.Visitor;
|
|
||||||
import ru.kayashov.bar.repository.CocktailRepository;
|
import ru.kayashov.bar.repository.CocktailRepository;
|
||||||
import ru.kayashov.bar.repository.IngredientRepository;
|
import ru.kayashov.bar.repository.IngredientRepository;
|
||||||
import ru.kayashov.bar.repository.ReceiptRepository;
|
import ru.kayashov.bar.repository.ReceiptRepository;
|
||||||
@@ -37,7 +35,6 @@ import javax.persistence.criteria.Order;
|
|||||||
import javax.persistence.criteria.Predicate;
|
import javax.persistence.criteria.Predicate;
|
||||||
import javax.persistence.criteria.Root;
|
import javax.persistence.criteria.Root;
|
||||||
import javax.persistence.criteria.Subquery;
|
import javax.persistence.criteria.Subquery;
|
||||||
import javax.print.attribute.standard.MediaSize;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -82,7 +79,8 @@ public class CocktailService {
|
|||||||
|
|
||||||
criteriaQuery.distinct(true);
|
criteriaQuery.distinct(true);
|
||||||
if (!dto.getAll()) {
|
if (!dto.getAll()) {
|
||||||
List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
|
// List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
|
||||||
|
List<Long> cocktailIds = findCocktailByCountNotHaveIngredient();
|
||||||
Predicate pr = root.get("id").in(cocktailIds);
|
Predicate pr = root.get("id").in(cocktailIds);
|
||||||
predicates.add(pr);
|
predicates.add(pr);
|
||||||
}
|
}
|
||||||
@@ -225,35 +223,18 @@ public class CocktailService {
|
|||||||
group by r.cocktail_id) as cifc
|
group by r.cocktail_id) as cifc
|
||||||
where false_count = 0
|
where false_count = 0
|
||||||
*/
|
*/
|
||||||
private List<Long> findCocktailByCountNotHaveIngredient(Integer notHaveCount, List<Long> currentIngredient) {
|
//todo: так и не придумал я нормальный запрос
|
||||||
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
|
private List<Long> findCocktailByCountNotHaveIngredient() {
|
||||||
List<Predicate> predicates = new ArrayList<>();
|
String sql = "SELECT cifc.cocktail_id" +
|
||||||
CriteriaQuery<Long> mainQuery = cb.createQuery(Long.class);
|
" FROM (SELECT r.cocktail_id," +
|
||||||
|
" COUNT(CASE WHEN i.is_have = false THEN 1 END) AS false_count" +
|
||||||
|
" FROM receipt r" +
|
||||||
|
" LEFT JOIN public.ingredient i ON i.id = r.ingredient_id" +
|
||||||
|
" GROUP BY r.cocktail_id) AS cifc" +
|
||||||
|
" WHERE false_count = 0";
|
||||||
|
|
||||||
// Создаем корневые сущности
|
javax.persistence.Query query = entityManager.createNativeQuery(sql);
|
||||||
Subquery<Long> sq = mainQuery.subquery(Long.class);
|
return query.getResultList();
|
||||||
Root<ReceiptEntity> rsq = sq.from(ReceiptEntity.class);
|
|
||||||
Join<ReceiptEntity, IngredientEntity> ingredientJoin = rsq.join("ingredient", JoinType.LEFT);
|
|
||||||
// Создаем подзапрос
|
|
||||||
sq.select(cb.count(cb.selectCase(cb.isFalse(ingredientJoin.get("isHave")))))
|
|
||||||
.groupBy(rsq.get("cocktail"))
|
|
||||||
.having(cb.equal(sq.getSelection(), notHaveCount));
|
|
||||||
|
|
||||||
// Создаем внешний запрос
|
|
||||||
mainQuery.select(rsq.get("cocktail"));
|
|
||||||
Predicate predicate = cb.exists(sq);
|
|
||||||
predicates.add(predicate);
|
|
||||||
// mainQuery.where(cb.exists(sq));
|
|
||||||
|
|
||||||
if(!currentIngredient.isEmpty()) {
|
|
||||||
predicates.add(rsq.get("ingredient").in(currentIngredient));
|
|
||||||
}
|
|
||||||
|
|
||||||
mainQuery.where(predicates.toArray(new Predicate[0]));
|
|
||||||
|
|
||||||
// Выполняем запрос
|
|
||||||
return entityManager.createQuery(mainQuery)
|
|
||||||
.getResultList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CocktailForListResponseDto findById(Long id) {
|
public CocktailForListResponseDto findById(Long id) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ public class IngredientService {
|
|||||||
private final IngredientRepository repository;
|
private final IngredientRepository repository;
|
||||||
private final IngredientMapper mapper;
|
private final IngredientMapper mapper;
|
||||||
private final BarEntityRepository barEntityRepository;
|
private final BarEntityRepository barEntityRepository;
|
||||||
|
private final IngredientRepository ingredientRepository;
|
||||||
|
|
||||||
private TypeEntity findTypeByName(String name) {
|
private TypeEntity findTypeByName(String name) {
|
||||||
return typeRepository.findByName(name)
|
return typeRepository.findByName(name)
|
||||||
@@ -57,6 +58,8 @@ public class IngredientService {
|
|||||||
} else {
|
} else {
|
||||||
bar.getIngredients().remove(ingredientEntity);
|
bar.getIngredients().remove(ingredientEntity);
|
||||||
}
|
}
|
||||||
|
ingredientEntity.setIsHave(isHave);
|
||||||
|
ingredientRepository.save(ingredientEntity);
|
||||||
barEntityRepository.save(bar);
|
barEntityRepository.save(bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,14 +4,20 @@ import lombok.RequiredArgsConstructor;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
|
||||||
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
|
||||||
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
|
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
|
||||||
|
import ru.kayashov.bar.model.entity.BarEntity;
|
||||||
import ru.kayashov.bar.model.entity.CocktailEntity;
|
import ru.kayashov.bar.model.entity.CocktailEntity;
|
||||||
|
import ru.kayashov.bar.model.entity.IngredientEntity;
|
||||||
import ru.kayashov.bar.model.entity.Visitor;
|
import ru.kayashov.bar.model.entity.Visitor;
|
||||||
|
import ru.kayashov.bar.repository.BarEntityRepository;
|
||||||
import ru.kayashov.bar.repository.CocktailRepository;
|
import ru.kayashov.bar.repository.CocktailRepository;
|
||||||
|
import ru.kayashov.bar.repository.IngredientRepository;
|
||||||
import ru.kayashov.bar.repository.VisitorsRepository;
|
import ru.kayashov.bar.repository.VisitorsRepository;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@@ -20,6 +26,8 @@ public class SessionService {
|
|||||||
|
|
||||||
private final VisitorsRepository visitorsRepository;
|
private final VisitorsRepository visitorsRepository;
|
||||||
private final CocktailRepository cocktailRepository;
|
private final CocktailRepository cocktailRepository;
|
||||||
|
private final BarEntityRepository barEntityRepository;
|
||||||
|
private final IngredientRepository ingredientRepository;
|
||||||
|
|
||||||
public Visitor getVisitor() {
|
public Visitor getVisitor() {
|
||||||
Long id = ((Visitor) SecurityContextHolder.getContext()
|
Long id = ((Visitor) SecurityContextHolder.getContext()
|
||||||
@@ -40,4 +48,42 @@ public class SessionService {
|
|||||||
.build())
|
.build())
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void changeActiveBar(Long id) {
|
||||||
|
BarEntity lastBar = barEntityRepository.findByActiveTrue().orElseThrow();
|
||||||
|
lastBar.setActive(false);
|
||||||
|
barEntityRepository.save(lastBar);
|
||||||
|
|
||||||
|
lastBar.getIngredients().stream()
|
||||||
|
.peek(i -> i.setIsHave(false))
|
||||||
|
.forEach(ingredientRepository::save);
|
||||||
|
|
||||||
|
BarEntity barEntity = barEntityRepository.findById(id).orElseThrow();
|
||||||
|
barEntity.setActive(true);
|
||||||
|
|
||||||
|
barEntity.getIngredients().stream()
|
||||||
|
.peek(i -> i.setIsHave(true))
|
||||||
|
.forEach(ingredientRepository::save);
|
||||||
|
|
||||||
|
barEntityRepository.save(barEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BarResponseDto> findAllBar() {
|
||||||
|
return barEntityRepository.findAll().stream()
|
||||||
|
.map(BarResponseDto::mapToDto)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteBar(Long id) {
|
||||||
|
barEntityRepository.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public BarResponseDto createBar(String name) {
|
||||||
|
BarEntity bar = new BarEntity();
|
||||||
|
bar.setName(name);
|
||||||
|
bar.setActive(false);
|
||||||
|
bar = barEntityRepository.save(bar);
|
||||||
|
|
||||||
|
return BarResponseDto.mapToDto(bar);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user