добавлена страница калькулятора

This commit is contained in:
Kayashov.SM
2025-08-21 02:49:24 +04:00
parent 34295bc045
commit 9da769beb5
22 changed files with 344 additions and 55 deletions

View File

@@ -13,6 +13,7 @@ import {EditIngredientPage} from "./pages/ingredients/EditIngredientPage";
import {EditCocktailPage} from "./pages/cocktails/EditCocktailPage";
import {useEffect, useState} from "react";
import {BarChangePage} from "./pages/BarChangePage";
import {CalcPage} from "./pages/calc/CalcPage";
export function NavigationRoutes() {
const {auth} = useAuth();
@@ -59,6 +60,11 @@ const authPages = [
children: (<LoginPage/>),
isPrivate: false,
},
{
path: paths.bar.calc,
children: (<CalcPage/>),
isPrivate: true,
},
{
path: paths.dashboard.overview,
isPrivate: true,
@@ -96,11 +102,16 @@ const authPages = [
const guestPages = [
{
path: paths.home,
isPrivate: false,
children: (<HomeRedirect auth={false}/>),
path: paths.dashboard.overview,
isPrivate: true,
children: (<MenuPage/>),
exact: true,
},
{
children: (<HomeRedirect auth={true}/>),
isPrivate: false,
path: paths.home,
},
{
path: paths.auth.tg,
isPrivate: false,

View File

@@ -0,0 +1,110 @@
import Typography from "@mui/material/Typography";
import * as React from "react";
import {useEffect, useMemo} from "react";
import {api} from "../../../lib/clients/api";
import {requests} from "../../../requests";
import {useAlert} from "../../../hooks/useAlert";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import {CocktailItemCalc} from "./CocktailItemCalc";
import {IngredientCalcCard} from "./IngredientCalcCard";
export function CalcPage() {
const {createError} = useAlert();
const [cocktails, setCocktails] = React.useState([]);
const [load, setLoad] = React.useState(false);
const [cocktailMap, setCocktailMap] = React.useState([]);
const changeHandler = (id, value) => {
setCocktailMap((prev) => ({
...prev,
[id]: value
}));
}
useEffect(() => {
if (load) {
return;
}
api().get(requests.cocktails.calc)
.then((r) => {
const data = r.data;
if (data.length === 0) {
setLoad(false);
return;
}
setCocktails(data);
let map = [];
data.map((d) => {
map[d.id] = 1
})
setCocktailMap(map);
setLoad(true);
})
.catch((r) => {
setLoad(true);
createError("Ошибка загрузки данных от сервера Status:" + r.code)
})
// eslint-disable-next-line
}, [load]);
const ingredients = useMemo(() => {
let map = {}
if (!cocktails) {
return [];
}
cocktails.forEach((c) => {
const receipts = c.receipt;
const countMeter = cocktailMap[c.id];
if (!receipts) {
return
}
receipts.forEach((r) => {
const ingredient = r.ingredient;
const id = ingredient.id;
const ingredientCount = r.count;
const resultCount = ingredientCount * countMeter;
if (map[id]) {
map[id] = {
...map[id],
count: map[id].count + resultCount
}
} else {
map[id] = {
ingredient: ingredient,
count: resultCount
}
}
})
})
return Object.values(map);
},
[cocktails, cocktailMap])
const deleteHandler = (id) => {
const state = cocktails.filter((c) => c.id !== id);
setCocktails(state);
}
return (
<Box padding={2}>
<Typography variant="h4" align="center">Коктейли</Typography>
<Stack mt={2}>
{cocktails.map((item, i) => (
<CocktailItemCalc key={i} cocktail={item} deleteHandler={deleteHandler}
changeHandler={changeHandler}/>
))}
</Stack>
<Typography variant="h4" mt={2} align="center">Ингредиенты</Typography>
<Stack mt={2}>
{ingredients.map((item, i) => (
<IngredientCalcCard key={i} count={item.count} ingredient={item.ingredient}/>
))}
</Stack>
</Box>
)
}

View File

@@ -0,0 +1,40 @@
import {Card} from "@mui/material";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import DeleteIcon from "@mui/icons-material/Delete";
import React from "react";
import Typography from "@mui/material/Typography";
import {Counter} from "./Counter";
export function CocktailItemCalc({cocktail, deleteHandler, changeHandler}) {
return (
<Card sx={{mb: 1, height: '250px', display: 'relative', p: 2}}>
<Stack justifyContent={'start'} spacing={2}>
<Stack direction='row' justifyContent='start' alignItems='center'>
<Box sx={{width: '100px', height: '100px'}}>
<img src={cocktail.image} loading='lazy' height={'100px'} width={'100px'} alt={cocktail.id}/>
</Box>
<Box sx={{width: 'calc(90% - 100px)', pr: 2, ml: 2}}>
<Stack>
<Typography>{cocktail.name}</Typography>
<Typography>{cocktail.volume}</Typography>
<Typography>{cocktail.category}</Typography>
<Typography>{cocktail.alcoholic}</Typography>
<Typography color={'textSecondary'}>{cocktail.components}</Typography>
</Stack>
</Box>
<Stack direction='row'>
<Stack sx={{width: '5%'}} spacing={1} justifyContent='flex-start'>
<IconButton size='small' onClick={() => deleteHandler(cocktail.id)}>
<DeleteIcon/>
</IconButton>
</Stack>
</Stack>
</Stack>
<Counter id={cocktail.id} changeHandler={changeHandler}/>
</Stack>
</Card>
)
}

View File

@@ -0,0 +1,65 @@
import React, {useState} from 'react';
import {Box, TextField, Button} from '@mui/material';
import {styled} from '@mui/material/styles';
// Стилизуем контейнер счетчика
const CounterContainer = styled(Box)`
display: flex;
align-items: center;
justify-content: center;
width: 150px;
height: 50px;
border-radius: 8px;
//box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
//background-color: #ffffff;
`;
export function Counter({id, changeHandler}) {
const [value, setValue] = useState(1);
const handleChange = (newValue) => {
setValue(newValue);
changeHandler(id, newValue);
}
return (
<Box>
<Button onClick={() => {
if (value > 0) {
setValue(value - 1);
}
}}
sx={{
width: '20px',
height: '55px',
borderRadius: '50%',
margin: '0 8px',
backgroundColor: 'transparent',
}}></Button>
<TextField
value={value}
onChange={(e) => {
const newValue = parseInt(e.target.value, 10);
if (!isNaN(newValue)) {
handleChange(newValue);
}
}}
inputProps={{inputMode: 'numeric'}}
sx={{
width: '40px',
height: '15px',
fontSize: '10px',
textAlign: 'center'
}}
/>
<Button onClick={() => handleChange(value + 1)}
sx={{
width: '20px',
height: '55px',
borderRadius: '50%',
margin: '0 8px',
backgroundColor: 'transparent',
}}>+</Button>
</Box>
);
}

View File

@@ -0,0 +1,21 @@
import {Card} from "@mui/material";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import React from "react";
export function IngredientCalcCard({ingredient, count}) {
return (
<Card sx={{mb: 1, height: '130px', display: 'relative', pt: 1}}>
<Stack direction='row' justifyContent='start' alignItems='center'>
<Box sx={{width: '100px', height: '100px'}}>
<img src={ingredient.image} loading='lazy' height={'100px'} width={'100px'} alt={ingredient.id}/>
</Box>
<Box sx={{width: 'calc(90% - 100px)', pr: 2}}>{ingredient.name}</Box>
<Stack direction='row'>
<Box mr={1} pt={'3px'}>{count}</Box>
</Stack>
</Stack>
</Card>
)
}

View File

@@ -65,7 +65,8 @@ export function Cocktail({row, handleFavourite, handleChangeRating, handleSelect
{renderFavouriteBadge(handleFavourite, row)}
{renderRating(handleChangeRating, row)}
{user.role !== 'USER' &&
{
(user.role && user.role !== 'USER') &&
<>
<IconButton size='small' href={`${paths.bar.cocktailEdit}?id=${row.id}`}>
<EditIcon fontSize='small'/>

View File

@@ -132,7 +132,7 @@ export function CocktailInfoModal({row}) {
<Stack key={r.ingredient.id} direction='row' justifyContent={'space-between'}
mt={1}>
<Stack direction='row'>
{user.role !== "USER" && (
{(user.role && user.role !== "USER") && (
<IconButton size="small" sx={{pb: "2px"}}
onClick={() => selectIngredientHandler(r.ingredient)}>
{r.ingredient.isHave
@@ -161,7 +161,7 @@ export function CocktailInfoModal({row}) {
</Box>
</DialogContent>
<DialogActions>
{user.role.includes("ADMIN") && (
{(user.role && user.role.includes("ADMIN")) && (
<Button href={`${paths.bar.cocktailEdit}?id=${cocktail.id}`}>Редактировать</Button>
)}
<Button onClick={closeCocktail}>Закрыть</Button>

View File

@@ -7,11 +7,13 @@ import MenuList from '@mui/material/MenuList';
import Popover from '@mui/material/Popover';
import Typography from '@mui/material/Typography';
import {SignOut as SignOutIcon} from '@phosphor-icons/react/dist/ssr/SignOut';
import {SignIn as SignInIcon} from '@phosphor-icons/react/dist/ssr/SignIn';
import {logger} from "../../lib/DefaultLogger";
import {useAuth} from "../../hooks/useAuth";
import {authClient} from "../../lib/clients/AuthClient";
import {useLocation} from "react-router-dom";
import {useUser} from "../../hooks/useUser";
import {paths} from "../../path";
export function UserPopover({anchorEl, onClose, open}) {
const {checkSession} = useAuth();
@@ -64,24 +66,28 @@ export function UserPopover({anchorEl, onClose, open}) {
{/* </ListItemIcon>*/}
{/* Профиль*/}
{/*</MenuItem>*/}
<MenuItem onClick={handleSignOut}>
<ListItemIcon>
<SignOutIcon fontSize="var(--icon-fontSize-md)"/>
</ListItemIcon>
Выход
</MenuItem>
{!user.name ? <MenuItem onClick={() => window.location.replace(paths.auth.signIn)}>
<ListItemIcon>
<SignInIcon fontSize="var(--icon-fontSize-md)"/>
</ListItemIcon>
Вход
</MenuItem> :
<MenuItem onClick={handleSignOut}>
<ListItemIcon>
<SignOutIcon fontSize="var(--icon-fontSize-md)"/>
</ListItemIcon>
Выход
</MenuItem>
}
</MenuList>
</Popover>
);
}
function userDescriptor(user, session) {
if (!user) {
return (<Typography variant="subtitle1">Ошибка загрузки данных</Typography>);
function userDescriptor(user) {
if (!user.name) {
return (<Typography variant="subtitle1">Гость</Typography>);
}
const open = (session.isActive && user.invited) ? "открыт" : "закрыт";
return (
<>
<Typography variant="subtitle1">{user.name + " " + user.lastName}</Typography>

View File

@@ -14,7 +14,8 @@ import {
Martini,
Storefront,
Users,
Wallet
Wallet,
Calculator
} from "@phosphor-icons/react";
export const navIcons = {
@@ -31,6 +32,7 @@ export const navIcons = {
'chart-pie': ChartPieIcon,
'gear-six': GearSixIcon,
'plugs-connected': PlugsConnectedIcon,
'calc': Calculator,
'x-square': XSquare,
user: UserIcon,
users: UsersIcon,

View File

@@ -1,10 +1,8 @@
import * as React from "react";
import {createContext, useCallback, useEffect, useState} from "react";
import {logger} from "../lib/DefaultLogger";
import {userClient} from "../lib/clients/UserClient";
import {tokenUtil} from "../lib/TokenUtil";
import {createContext, useCallback, useEffect, useState} from "react";
import {api} from "../lib/clients/api";
import {requests} from "../requests";
export const UserContext = createContext(undefined);
@@ -24,19 +22,10 @@ export function UserProvider({children}) {
const checkSession = useCallback(async () => {
try {
setState((prev) => ({...prev, isLoading: true}));
if (!await tokenUtil.checkToken(tokenUtil.getToken())) {
if (!tokenUtil.checkToken(tokenUtil.getToken())) {
setState((prev) => ({...prev, error: '', isLoading: false, user: {}}));
return;
}
api().get(requests.bar.session.status)
.then((r) => setState((prevState) => ({
...prevState,
session: r.data
})))
.catch(() => setState((prevState) => ({
...prevState,
session: {}
})))
if (Object.keys(state.user).length === 0) {
const {data, errorData} = await userClient.getMe();
if (errorData) {

View File

@@ -5,5 +5,6 @@ export const navItems = [
{key: 'barList', title: 'Список баров', href: paths.bar.list, 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: 'cocktailEdit', title: 'Коктейли', href: paths.bar.cocktailEdit, icon: 'cocktail', forAdmin: true}
{key: 'cocktailEdit', title: 'Коктейли', href: paths.bar.cocktailEdit, icon: 'cocktail', forAdmin: true},
{key: 'calc', title: 'Калькулятор', href: paths.bar.calc, icon: 'calc', forAdmin: true},
];

View File

@@ -17,7 +17,8 @@ export const paths = {
cocktails: "/cocktails",
ingredientEdit: '/ingredients/edit',
cocktailEdit: '/cocktail/edit',
menu: '/menuList'
menu: '/menuList',
calc: '/calc',
},
errors: {notFound: '/errors/not-found'},
notFound: '*',

View File

@@ -29,7 +29,8 @@ export const requests = {
rating: routes.cocktails + "/rating?id=",
receipts: routes.cocktails + "/receipts?id=",
byIngredient: routes.cocktails + "/byIngredient?id=",
instructions: routes.cocktails + "/instructions?id="
instructions: routes.cocktails + "/instructions?id=",
calc: routes.cocktails + "/calc",
},
visitors: {
all: routes.visitor,

View File

@@ -15,6 +15,7 @@ import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import ru.kayashov.bar.security.JwtTokenProvider;
import javax.annotation.security.PermitAll;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
@@ -29,6 +30,7 @@ public class AuthController {
private final VisitorsRepository visitorsRepository;
private final PasswordEncoder passwordEncoder;
@PermitAll
@PostMapping("/login")
public AuthResponseDto checkTelegramChat(@RequestBody AuthRequestDto dto) {
if (dto.getByLogin()) {
@@ -75,6 +77,7 @@ public class AuthController {
}
}
@PermitAll
@PostMapping("refresh")
public AuthResponseDto refreshToken(@RequestHeader("Authorization") String token) {
Claims claims = jwtTokenProvider.extractAllClaims(token);

View File

@@ -16,12 +16,12 @@ import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.model.entity.Category;
import ru.kayashov.bar.model.entity.Glass;
import ru.kayashov.bar.model.entity.Unit;
import ru.kayashov.bar.model.entity.UserRole;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.UnitRepository;
import ru.kayashov.bar.service.SessionService;
import ru.kayashov.bar.service.VisitorService;
import javax.annotation.security.PermitAll;
import java.util.Arrays;
import java.util.List;
@@ -36,21 +36,25 @@ public class BarController {
private final VisitorService visitorService;
private final UnitRepository unitRepository;
@PermitAll
@GetMapping("/units")
public List<Unit> getUnitList() {
return unitRepository.findAll();
}
@PermitAll
@GetMapping("/glass")
public List<String> getGlass() {
return Arrays.stream(Glass.values()).map(Glass::getName).toList();
}
@PermitAll
@GetMapping("/category")
public List<String> getCategory() {
return Arrays.stream(Category.values()).map(Category::getName).toList();
}
@PermitAll
@GetMapping("/receipt")
public List<ReceiptResponseDto> getReceipt(@RequestParam("id") Long id) {
return sessionService.getReceiptList(id);

View File

@@ -3,7 +3,6 @@ package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -15,16 +14,16 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import ru.kayashov.bar.controller.dto.ErrorDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailFilterRequestDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailForIngredientModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailForListResponseDto;
import ru.kayashov.bar.controller.dto.ErrorDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.service.CocktailService;
import javax.annotation.security.PermitAll;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@@ -39,11 +38,17 @@ public class CocktailController {
private final CocktailService cocktailService;
//получить все
@PermitAll
@PostMapping("menu")
public List<CocktailForListResponseDto> menu(@RequestBody CocktailFilterRequestDto dto) {
return cocktailService.getMenu(dto);
}
@GetMapping("calc")
public List<CocktailForListResponseDto> calc() {
return cocktailService.calc();
}
@GetMapping("/instructions")
public String getInstructions(@RequestParam("id") Long id) {
return cocktailService.findInstructions(id);
@@ -56,7 +61,7 @@ public class CocktailController {
@PostMapping("/photo")
public String savePhoto(@RequestBody MultipartFile file) throws IOException {
if(file == null) {
if (file == null) {
return "";
}
return cocktailService.savePhoto(file);

View File

@@ -10,7 +10,7 @@ import java.util.List;
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class CocktailFilterRequestDto {
private String search;
private String search = "";
private Boolean onlyFavourite;
private List<String> glass;
private List<String> category;

View File

@@ -11,9 +11,12 @@ import ru.kayashov.bar.model.entity.IngredientEntity;
public class IngredientSimpleResponseDto {
private Long id;
private String name;
private String image;
private Boolean isHave;
public static IngredientSimpleResponseDto mapToDto(IngredientEntity ingredient) {
return new IngredientSimpleResponseDto(ingredient.getId(), ingredient.getName(), false/*ingredient.getIsHave()*/);
return new IngredientSimpleResponseDto(ingredient.getId(), ingredient.getName(),
"https://thecocktaildb.com/images/ingredients/" + ingredient.getEnName() + "-Medium.png",
ingredient.getIsHave());
}
}

View File

@@ -1,6 +1,8 @@
package ru.kayashov.bar.mapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@@ -30,15 +32,12 @@ public class CocktailMapper {
private final BarEntityRepository barRepository;
@Transactional
public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all) {
public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all, boolean withReceipts) {
Visitor visitor = getCurrentVisitor();
// if(checkUserNotInBar(visitor)) {
// return new ArrayList<>();
// }
List<Long> barStopList = new ArrayList<>();
List<Long> allowedIngredients = getAllowedIngredients();
return cocktails.stream()
.map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList))
.map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList, withReceipts))
// .filter(c -> all || c.getIsAllowed())
// .filter(c -> all || c.getInMenu())
.toList();
@@ -59,7 +58,7 @@ public class CocktailMapper {
.build();
}
private CocktailForListResponseDto cocktailToDto(CocktailEntity e, Visitor visitor, List<Long> allowedIngredients, List<Long> barStopList) {
private CocktailForListResponseDto cocktailToDto(CocktailEntity e, Visitor visitor, List<Long> allowedIngredients, List<Long> barStopList, boolean withReceipts) {
boolean hasError = false;
int volume = 0;
Float abv = 0f;
@@ -106,8 +105,8 @@ public class CocktailMapper {
.rating(createRatingDto(e))
.isAllowed(calculateAllowed(e.getReceipt(), allowedIngredients))
.inMenu(!barStopList.contains(e.getId()))
.receipt(!withReceipts ? null : e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList())
.build();
// d.setReceipt(e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList());
}
private List<Long> getAllowedIngredients() {
@@ -148,7 +147,14 @@ public class CocktailMapper {
}
private Visitor getCurrentVisitor() {
Long visitorId = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
SecurityContext context = SecurityContextHolder.getContext();
Authentication authentication = context.getAuthentication();
Long visitorId;
if (authentication.getPrincipal() instanceof Visitor) {
visitorId = ((Visitor) authentication.getPrincipal()).getId();
} else {
visitorId = 1L;
}
return visitorsRepository.findById(visitorId).orElseThrow(RuntimeException::new);
}
@@ -181,7 +187,7 @@ public class CocktailMapper {
}
private IngredientSimpleResponseDto createIngredientResponseDto(IngredientEntity i, List<Long> allowedIngredients) {
return new IngredientSimpleResponseDto(i.getId(), i.getName(), allowedIngredients.contains(i.getId()));
return new IngredientSimpleResponseDto(i.getId(), i.getName(), "https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png", allowedIngredients.contains(i.getId()));
}

View File

@@ -54,6 +54,8 @@ public class IngredientMapper {
}
private IngredientSimpleResponseDto mapIngredientToSimpleDto(IngredientEntity i, List<Long> allowedIngredients) {
return new IngredientSimpleResponseDto(i.getId(), i.getName(), allowedIngredients.contains(i.getId()));
return new IngredientSimpleResponseDto(i.getId(), i.getName(),
"https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png",
allowedIngredients.contains(i.getId()));
}
}

View File

@@ -7,6 +7,7 @@ import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
@@ -26,6 +27,7 @@ import static org.springframework.security.config.http.SessionCreationPolicy.STA
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@RequiredArgsConstructor
public class SecurityConfig {
@@ -51,8 +53,11 @@ public class SecurityConfig {
private void authorizeConfiguration(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry request) {
request
// Можно указать конкретный путь, * - 1 уровень вложенности, ** - любое количество уровней вложенности
.antMatchers("/api/auth/**")
.permitAll()
.antMatchers("/api/auth/**").permitAll()
.antMatchers("/api/cocktail/menu").permitAll()
.antMatchers("/api/bar/category").permitAll()
.antMatchers("/api/bar/glass").permitAll()
.antMatchers("/api/ingredient/simple").permitAll()
.anyRequest()
.authenticated();
}

View File

@@ -14,6 +14,7 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailForListResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.SortingEnum;
import ru.kayashov.bar.mapper.CocktailMapper;
import ru.kayashov.bar.model.entity.Alcoholic;
import ru.kayashov.bar.model.entity.Category;
@@ -67,7 +68,19 @@ public class CocktailService {
*/
@Transactional
public List<CocktailForListResponseDto> getMenu(CocktailFilterRequestDto dto) {
return mapper.cocktailsToDtoList(criteria(dto), dto.getAll());
return mapper.cocktailsToDtoList(criteria(dto), dto.getAll(), false);
}
@Transactional
public List<CocktailForListResponseDto> calc() {
CocktailFilterRequestDto dto = new CocktailFilterRequestDto();
dto.setPage(0);
dto.setSize(1000);
dto.setAll(false);
dto.setOnlyFavourite(false);
dto.setSort(SortingEnum.NAME_ASC);
return mapper.cocktailsToDtoList(criteria(dto),false, true);
}
private List<CocktailEntity> criteria(CocktailFilterRequestDto dto) {