большая доработка чистоты кода в части бек

This commit is contained in:
Kayashov.SM
2025-08-22 03:18:30 +04:00
parent 488638885c
commit 198be069b4
37 changed files with 481 additions and 609 deletions

View File

@@ -4,6 +4,7 @@ import io.jsonwebtoken.Claims;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
@@ -11,9 +12,11 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.controller.dto.AuthRequestDto;
import ru.kayashov.bar.controller.dto.AuthResponseDto;
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import ru.kayashov.bar.security.JwtTokenProvider;
import ru.kayashov.bar.service.VisitorService;
import javax.annotation.security.PermitAll;
import java.nio.charset.StandardCharsets;
@@ -29,6 +32,7 @@ public class AuthController {
private final JwtTokenProvider jwtTokenProvider;
private final VisitorsRepository visitorsRepository;
private final PasswordEncoder passwordEncoder;
private final VisitorService visitorService;
@PermitAll
@PostMapping("/login")
@@ -40,6 +44,45 @@ public class AuthController {
}
}
@PermitAll
@PostMapping("refresh")
public AuthResponseDto refreshToken(@RequestHeader("Authorization") String token) {
Claims claims = jwtTokenProvider.extractAllClaims(token);
Long visitorId = claims.get("id", Long.class);
log.info("обновление токена для пользователя {}", visitorId);
Visitor visitor = visitorsRepository.findById(visitorId).orElseThrow();
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
}
@GetMapping("/getMe")
public VisitorResponseDto getMe() {
Visitor visitor = visitorService.getCurrentVisitor();
VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, true, visitor.getRole().toString(), true);
log.info("Запрос информации о пользователе: {}-{} {}, вошел в бар",
dto.getId(),
dto.getName().strip(),
dto.getLastName() != null ? dto.getLastName().strip() : "");
return dto;
}
private AuthResponseDto checkLogin(String login, String password) {
if (login == null || login.isEmpty() || password == null || password.isEmpty()) {
return new AuthResponseDto(null, "Поля не могут быть пустые");
}
Optional<Visitor> visitorOpt = visitorsRepository.findByLogin(login);
if (visitorOpt.isEmpty()) {
return new AuthResponseDto(null, "Не найдет пользователь " + login);
}
Visitor visitor = visitorOpt.get();
log.info("Попытка авторизации пользователя {}", visitor.getId());
if (passwordEncoder.matches(password, visitor.getPassword())) {
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
} else {
return new AuthResponseDto(null, "Неверный логин или пароль");
}
}
private AuthResponseDto parseCode(String code) {
String decode = new String(Base64.getDecoder().decode(code), StandardCharsets.UTF_8);
String[] decodeArr = decode.split(":");
@@ -59,32 +102,4 @@ public class AuthController {
return new AuthResponseDto(null, "Неверный код подтверждения");
}
private AuthResponseDto checkLogin(String login, String password) {
if (login == null || login.isEmpty() || password == null || password.isEmpty()) {
return new AuthResponseDto(null, "Поля не могут быть пустые");
}
Optional<Visitor> visitorOpt = visitorsRepository.findByLogin(login);
if (visitorOpt.isEmpty()) {
return new AuthResponseDto(null, "Не найдет пользователь " + login);
}
Visitor visitor = visitorOpt.get();
log.info("Попытка авторизации пользователя {}", visitor.getId());
if (passwordEncoder.matches(password, visitor.getPassword())) {
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
} else {
return new AuthResponseDto(null, "Неверный логин или пароль");
}
}
@PermitAll
@PostMapping("refresh")
public AuthResponseDto refreshToken(@RequestHeader("Authorization") String token) {
Claims claims = jwtTokenProvider.extractAllClaims(token);
Long visitorId = claims.get("id", Long.class);
log.info("обновление токена для пользователя {}", visitorId);
Visitor visitor = visitorsRepository.findById(visitorId).orElseThrow();
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
}
}

View File

@@ -8,86 +8,38 @@ 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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
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.model.entity.Category;
import ru.kayashov.bar.model.entity.Glass;
import ru.kayashov.bar.model.entity.Unit;
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 ru.kayashov.bar.service.BarService;
import javax.annotation.security.PermitAll;
import java.util.Arrays;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/bar/")
@RequestMapping("/api/bar")
@RequiredArgsConstructor
public class BarController {
private final SessionService sessionService;
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);
}
private final BarService barService;
@PostMapping("/change/{id}")
public void changeActiveBar(@PathVariable Long id) {
sessionService.changeActiveBar(id);
barService.changeActiveBar(id);
}
@DeleteMapping("/{id}")
public void deleteBar(@PathVariable Long id) {
sessionService.deleteBar(id);
barService.deleteBar(id);
}
@PostMapping("/{name}")
public BarResponseDto createBar(@PathVariable String name) {
return sessionService.createBar(name);
return barService.createBar(name);
}
@GetMapping("/all")
public List<BarResponseDto> getAll() {
return sessionService.findAllBar();
}
@GetMapping("/getMe")
public VisitorResponseDto getMe() {
Visitor visitor = visitorService.getCurrentVisitor();
VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, true, visitor.getRole().toString(), true);
log.info("Запрос информации о пользователе: {}-{} {}, вошел в бар",
dto.getId(),
dto.getName().strip(),
dto.getLastName() != null ? dto.getLastName().strip() : "");
return dto;
return barService.findAllBar();
}
}

View File

@@ -0,0 +1,25 @@
package ru.kayashov.bar.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.model.entity.Category;
import javax.annotation.security.PermitAll;
import java.util.Arrays;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/category")
public class CategoryController {
@PermitAll
@GetMapping
public List<String> getCategory() {
return Arrays.stream(Category.values()).map(Category::getName).toList();
}
}

View File

@@ -49,11 +49,6 @@ public class CocktailController {
return cocktailService.calc();
}
@GetMapping("/instructions")
public String getInstructions(@RequestParam("id") Long id) {
return cocktailService.findInstructions(id);
}
@GetMapping("/byIngredient")
public List<CocktailForIngredientModalDto> getByIngredient(@RequestParam Long id) {
return cocktailService.findByIngredient(id);
@@ -77,11 +72,6 @@ public class CocktailController {
return cocktailService.getSimple();
}
@GetMapping("/receipts")
public List<ReceiptResponseDto> getReceipts(@RequestParam Long id) {
return cocktailService.getReceipts(id);
}
@GetMapping("/modal")
public CocktailModalDto getForModal(@RequestParam Long id) {
return cocktailService.getForModal(id);

View File

@@ -0,0 +1,27 @@
package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.model.entity.Glass;
import javax.annotation.security.PermitAll;
import java.util.Arrays;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/glass")
@RequiredArgsConstructor
public class GlassController {
@PermitAll
@GetMapping
public List<String> getGlass() {
return Arrays.stream(Glass.values()).map(Glass::getName).toList();
}
}

View File

@@ -39,6 +39,8 @@ public class IngredientController {
return ingredientService.getAllSimple();
}
//todo: перевести на enum
@Deprecated
@GetMapping("/type")
public List<TypeResponseDto> getTypes() {
return typeRepository.findAll().stream()

View File

@@ -0,0 +1,30 @@
package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.service.ReceiptService;
import javax.annotation.security.PermitAll;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/receipt")
@RequiredArgsConstructor
public class ReceiptController {
private final ReceiptService receiptService;
@PermitAll
@GetMapping
public List<ReceiptResponseDto> getReceipt(@RequestParam("id") Long id) {
return receiptService.getReceiptList(id);
}
}

View File

@@ -0,0 +1,29 @@
package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.kayashov.bar.model.entity.Unit;
import ru.kayashov.bar.repository.UnitRepository;
import javax.annotation.security.PermitAll;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/unit")
@RequiredArgsConstructor
public class UnitController {
private final UnitRepository unitRepository;
@PermitAll
@GetMapping("/units")
public List<Unit> getUnitList() {
return unitRepository.findAll();
}
}

View File

@@ -21,8 +21,7 @@ public class VisitorResponseDto {
d.setId(e.getId());
d.setName(e.getName());
d.setLastName(e.getLastName());
// d.setInvited(e.getInvited());
// d.setRole(e.getRole().toString());
d.setRole(e.getRole().toString());
return d;
}

View File

@@ -37,27 +37,4 @@ public class CocktailForListResponseDto {
private List<ReceiptResponseDto> receipt;
private RatingResponseDto rating;
public static CocktailForListResponseDto mapToDto(CocktailEntity e, Long visitorId) {
CocktailForListResponseDto d = new CocktailForListResponseDto();
d.setId(e.getId());
d.setName(e.getName());
d.setImage(e.getImage());
d.setVideo(e.getVideo());
d.setInstructions(e.getInstructions());
d.setCategory(e.getCategory().getName());
d.setAlcoholic(e.getAlcoholic().getValue());
d.setGlass(e.getGlass().getName());
String components = e.getReceipt().stream().map(r -> r.getIngredient().getName()).collect(Collectors.joining(", "));
d.setComponents(components);
d.setReceipt(e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList());
RatingResponseDto rating = new RatingResponseDto();
rating.setFavourite(e.getIsFavorite());
rating.setRating(e.getRating());
d.setRating(rating);
return d;
}
}

View File

@@ -15,7 +15,6 @@ import ru.kayashov.bar.model.entity.IngredientEntity;
public class IngredientResponseDto {
private Long id;
private String name;
// private String enName;
private Boolean alcohol;
private Integer abv;
private boolean isHave;
@@ -29,11 +28,10 @@ public class IngredientResponseDto {
.builder()
.id(i.getId())
.name(i.getName())
// .enName(i.getEnName())
.alcohol(i.getAlcohol())
.type(i.getType() != null ? i.getType().getName() : null)
.abv(i.getAbv())
// .isHave(i.getIsHave())
.isHave(i.getIsHave())
.image("https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png")
.description(i.getDescription())
.build();

View File

@@ -12,15 +12,12 @@ import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.RatingResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
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.IngredientEntity;
import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -29,22 +26,15 @@ import java.util.stream.Collectors;
public class CocktailMapper {
private final VisitorsRepository visitorsRepository;
private final BarEntityRepository barRepository;
@Transactional
public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all, boolean withReceipts) {
Visitor visitor = getCurrentVisitor();
List<Long> barStopList = new ArrayList<>();
List<Long> allowedIngredients = getAllowedIngredients();
return cocktails.stream()
.map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList, withReceipts))
// .filter(c -> all || c.getIsAllowed())
// .filter(c -> all || c.getInMenu())
.map(c -> cocktailToDto(c, withReceipts))
.toList();
}
public CocktailForListResponseDto cocktailToFullDto(CocktailEntity e) {
List<Long> allowed = getAllowedIngredients();
return CocktailForListResponseDto.builder()
.id(e.getId())
.name(e.getName())
@@ -54,11 +44,11 @@ public class CocktailMapper {
.glass(e.getGlass().getName())
.instructions(e.getInstructions())
.video(e.getVideo())
.receipt(createReceiptDtoList(e.getReceipt(), allowed))
.receipt(createReceiptDtoList(e.getReceipt()))
.build();
}
private CocktailForListResponseDto cocktailToDto(CocktailEntity e, Visitor visitor, List<Long> allowedIngredients, List<Long> barStopList, boolean withReceipts) {
private CocktailForListResponseDto cocktailToDto(CocktailEntity e, boolean withReceipts) {
boolean hasError = false;
int volume = 0;
Float abv = 0f;
@@ -103,35 +93,11 @@ public class CocktailMapper {
.glass(e.getGlass().getName())
.components(containCocktailComponents(e.getReceipt()))
.rating(createRatingDto(e))
.isAllowed(calculateAllowed(e.getReceipt(), allowedIngredients))
.inMenu(!barStopList.contains(e.getId()))
.isAllowed(e.getAllowed())
.receipt(!withReceipts ? null : e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList())
.build();
}
private List<Long> getAllowedIngredients() {
return barRepository.findByActiveTrue()
.map(BarEntity::getIngredients)
.orElseThrow()
.stream()
.map(IngredientEntity::getId)
.toList();
// return visitor.getResidents().stream()
// .filter(BarResident::getActive)
// .map(BarResident::getBar)
// .map(BarEntity::getIngredients)
// .flatMap(List::stream)
// .map(BarIngredientStorage::getIngredient)
// .map(IngredientEntity::getId)
// .toList();
}
private Boolean calculateAllowed(List<ReceiptEntity> e, List<Long> allowedIngredients) {
return e.stream()
.map(ReceiptEntity::getIngredient)
.allMatch(i -> allowedIngredients.contains(i.getId()));
}
private RatingResponseDto createRatingDto(CocktailEntity entity) {
RatingResponseDto result = new RatingResponseDto();
result.setRating(entity.getRating());
@@ -159,35 +125,37 @@ public class CocktailMapper {
}
public CocktailModalDto cocktailToModalDto(CocktailEntity e) {
List<Long> allowedIngredients = getAllowedIngredients();
return CocktailModalDto.builder()
.id(e.getId())
.name(e.getName())
.image(e.getImage())
.instructions(e.getInstructions())
.rating(createRatingDto(e))
.receipt(createReceiptDtoList(e.getReceipt(), allowedIngredients))
.receipt(createReceiptDtoList(e.getReceipt()))
.build();
}
private List<ReceiptResponseDto> createReceiptDtoList(List<ReceiptEntity> receipts, List<Long> allowedIngredients) {
private List<ReceiptResponseDto> createReceiptDtoList(List<ReceiptEntity> receipts) {
return receipts.stream()
.map(r -> createReceiptDto(r, allowedIngredients))
.map(this::createReceiptDto)
.toList();
}
private ReceiptResponseDto createReceiptDto(ReceiptEntity e, List<Long> allowedIngredients) {
private ReceiptResponseDto createReceiptDto(ReceiptEntity e) {
return ReceiptResponseDto.builder()
.id(e.getId())
.ingredient(createIngredientResponseDto(e.getIngredient(), allowedIngredients))
.ingredient(createIngredientResponseDto(e.getIngredient()))
.count(e.getCount())
.unit(e.getUnit())
.measure(e.getMeasure())
.build();
}
private IngredientSimpleResponseDto createIngredientResponseDto(IngredientEntity i, List<Long> allowedIngredients) {
return new IngredientSimpleResponseDto(i.getId(), i.getName(), "https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png", allowedIngredients.contains(i.getId()));
private IngredientSimpleResponseDto createIngredientResponseDto(IngredientEntity i) {
return new IngredientSimpleResponseDto(i.getId(),
i.getName(),
"https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png",
i.getIsHave());
}

View File

@@ -4,9 +4,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.controller.dto.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.repository.BarEntityRepository;
import java.util.List;
@@ -14,25 +12,13 @@ import java.util.List;
@RequiredArgsConstructor
public class IngredientMapper {
private final BarEntityRepository barRepository;
public List<IngredientResponseDto> mapIngredientsToDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = getAllowedIngredients();
return ingredients.stream()
.map(i -> mapIngredientToDto(i, allowedIngredients))
.map(this::mapIngredientToDto)
.toList();
}
private List<Long> getAllowedIngredients() {
return barRepository.findByActiveTrue()
.map(BarEntity::getIngredients)
.orElseThrow()
.stream()
.map(IngredientEntity::getId)
.toList();
}
private IngredientResponseDto mapIngredientToDto(IngredientEntity i, List<Long> allowedIngredients) {
private IngredientResponseDto mapIngredientToDto(IngredientEntity i) {
return IngredientResponseDto
.builder()
.id(i.getId())
@@ -40,22 +26,21 @@ public class IngredientMapper {
.alcohol(i.getAlcohol())
.type(i.getType() != null ? i.getType().getName() : null)
.abv(i.getAbv())
.isHave(allowedIngredients.contains(i.getId()))
.isHave(i.getIsHave())
.image("https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png")
.description(i.getDescription())
.build();
}
public List<IngredientSimpleResponseDto> mapIngredientsToSimpleDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = getAllowedIngredients();
return ingredients.stream()
.map(i -> mapIngredientToSimpleDto(i, allowedIngredients))
.map(this::mapIngredientToSimpleDto)
.toList();
}
private IngredientSimpleResponseDto mapIngredientToSimpleDto(IngredientEntity i, List<Long> allowedIngredients) {
private IngredientSimpleResponseDto mapIngredientToSimpleDto(IngredientEntity i) {
return new IngredientSimpleResponseDto(i.getId(), i.getName(),
"https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png",
allowedIngredients.contains(i.getId()));
i.getIsHave());
}
}

View File

@@ -7,16 +7,10 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum Category {
COCKTAIL("Коктейль"),
PUNCH("Пунш"),
SHAKE("Шейк"),
OTHER("Другие"),
BEER("Пиво"),
HOMEMADE_LIQUEUR("Домашний ликер"),
SHOT("Шот"),
COCOA("Какао"),
COFFEE_TEA("Кофе-Чай"),
SOFT("Безалкогольный напиток"),
ORDINARY("Обычный напиток");
SOFT("Безалкогольный напиток");
private final String name;

View File

@@ -27,6 +27,7 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
public class CocktailEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@@ -46,10 +47,12 @@ public class CocktailEntity {
@Enumerated(EnumType.STRING)
private Glass glass;
private Integer rating;
private Boolean allowed;
private Integer rating = 0;
@Column(name = "favourite")
private Boolean isFavorite;
private Boolean isFavorite = false;
@OneToMany(mappedBy = "cocktail", cascade = CascadeType.REMOVE)
private List<ReceiptEntity> receipt;

View File

@@ -6,23 +6,20 @@ import lombok.RequiredArgsConstructor;
@Getter
@RequiredArgsConstructor
public enum Glass {
HIGHBALL("Хайболл"),
COCKTAIL("Коктейльный бокал"),
COLLINS("Стакан"),
POUSSE("Рюмка на ножке"),
CHAMPAGNE("Бокал флюте"),
BRANDY("Коньячный бокал"),
HURRICANE("Ураган"),
COFFEE("Кофейная кружка"),
SHOT("Рюмка"),
JAR("Банка"),
PITCHER("Кувшин"),
CORDIAL("Ликерная рюмка"),
BEER("Пивной бокал"),
WINE("Бокал для вина"),
MARGARITA("Бокал Маргарита");
HIGHBALL("Хайболл",250),
COCKTAIL("Коктейльный бокал",120),
COLLINS("Стакан", 200),
CHAMPAGNE("Бокал флюте", 200),
HURRICANE("Ураган", 350),
COFFEE("Кофейная кружка", 250),
SHOT("Рюмка",50),
CORDIAL("Ликерная рюмка",150),
BEER("Пивной бокал", 500),
WINE("Бокал для вина", 350),
MARGARITA("Бокал Маргарита", 260);
private final String name;
private final Integer capacity;
public static Glass findValue(String name) {
for (Glass glass : Glass.values()) {

View File

@@ -26,6 +26,7 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
public class IngredientEntity {
@Id
private Long id;
private String name;
@@ -44,7 +45,7 @@ public class IngredientEntity {
@JoinColumn(name = "type")
private TypeEntity type;
@ManyToMany(cascade = CascadeType.REMOVE)
@ManyToMany
@JoinTable(
name = "bar_ingredient",
joinColumns = @JoinColumn(name = "ingredient"),

View File

@@ -8,11 +8,17 @@ import org.springframework.transaction.annotation.Transactional;
import ru.kayashov.bar.model.entity.CocktailEntity;
public interface CocktailRepository extends JpaRepository<CocktailEntity, Long> {
@Modifying
@Transactional
@Query("UPDATE CocktailEntity c SET c.isFavorite = :favorite WHERE c.id = :id")
void updateFavouriteById(@Param("id") Long id, @Param("favorite") Boolean favorite);
@Modifying
@Transactional
@Query("UPDATE CocktailEntity c SET c.allowed = false WHERE c.allowed = true")
void markAllAsNotAllowed();
@Modifying
@Transactional
@Query("UPDATE CocktailEntity c SET c.rating = :rating WHERE c.id = :id")

View File

@@ -0,0 +1,101 @@
package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.kayashov.bar.controller.dto.bar.BarResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Slf4j
@Service
@RequiredArgsConstructor
public class BarService {
private final BarEntityRepository barEntityRepository;
private final IngredientRepository ingredientRepository;
private final CocktailRepository cocktailRepository;
// @Transactional
public void changeActiveBar(Long id) {
Optional<BarEntity> lastBarOpt = barEntityRepository.findByActiveTrue();
if (lastBarOpt.isPresent()) {
BarEntity lastBar = lastBarOpt.get();
lastBar.setActive(false);
barEntityRepository.save(lastBar);
lastBar.getIngredients().stream()
.peek(i -> i.setIsHave(false))
.forEach(ingredientRepository::save);
cocktailRepository.markAllAsNotAllowed();
log.info("Бар {} отключен", lastBar.getName());
}
BarEntity barEntity = barEntityRepository.findById(id).orElseThrow();
barEntity.setActive(true);
List<IngredientEntity> ingredients = barEntity.getIngredients().stream()
.peek(i -> i.setIsHave(true))
.map(ingredientRepository::save)
.toList();
cocktailRepository.saveAll(findAllowedCocktails(ingredients));
barEntityRepository.save(barEntity);
log.info("Бар {} подключен", barEntity.getName());
}
public List<BarResponseDto> findAllBar() {
List<BarEntity> barEntities = barEntityRepository.findAll();
log.info("По запросу найдено {} баров", barEntities.size());
return barEntities.stream()
.map(BarResponseDto::mapToDto)
.toList();
}
public void deleteBar(Long id) {
barEntityRepository.deleteById(id);
log.info("Бар с id {} удален", id);
}
public BarResponseDto createBar(String name) {
BarEntity bar = new BarEntity();
bar.setName(name);
bar.setActive(false);
bar = barEntityRepository.save(bar);
log.info("Создан бар {}", name);
return BarResponseDto.mapToDto(bar);
}
private List<CocktailEntity> findAllowedCocktails(List<IngredientEntity> ingredients) {
List<CocktailEntity> result = new ArrayList<>();
for (IngredientEntity ingredient : ingredients) {
List<CocktailEntity> cocktails = ingredient.getReceipts().stream()
.map(ReceiptEntity::getCocktail)
.toList();
for (CocktailEntity cocktail : cocktails) {
if (cocktail.getReceipt().stream().allMatch(r -> r.getIngredient().getIsHave())) {
cocktail.setAllowed(true);
result.add(cocktail);
}
}
}
return result;
}
}

View File

@@ -15,6 +15,7 @@ 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.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.mapper.CocktailMapper;
import ru.kayashov.bar.model.entity.Alcoholic;
import ru.kayashov.bar.model.entity.Category;
@@ -40,8 +41,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Slf4j
@Service
@@ -90,9 +89,7 @@ public class CocktailService {
criteriaQuery.distinct(true);
if (!dto.getAll()) {
// List<Long> cocktailIds = findICountCocktailIds(0, new ArrayList<>());
List<Long> cocktailIds = findCocktailByCountNotHaveIngredient();
Predicate pr = root.get("id").in(cocktailIds);
Predicate pr = cb.isTrue(root.get("allowed"));
predicates.add(pr);
}
@@ -123,18 +120,6 @@ public class CocktailService {
predicates.add(root.get("alcoholic").in(dto.getAlcohol().stream().map(Alcoholic::findValue).toList()));
}
if (dto.getNotHaveCount() != null) {
List<Long> approveCocktail = findICountCocktailIds(dto.getNotHaveCount(), dto.getIngredient());
predicates.add(root.get("id").in(approveCocktail));
}
//
// if (!dto.getSortField().equals("name") || !dto.getSortOrder().equals("asc")) {
// cb.asc(root.get("name"));
//// query.orderBy(cb.asc(root.get("name").get(dto.getSortField())));
// } else {
// criteriaQuery.orderBy(cb.asc(root.get("name")));
// }
//todo: доделать другие виды сортировки
Order order;
switch (dto.getSort()) {
@@ -154,100 +139,6 @@ public class CocktailService {
return cocktailEntities;
}
private List<Long> findICountCocktailIds(Integer iCount, List<String> ingredientFilter) {
List<Long> allowedIngredient = visitorService.getAllowedIngredients();
Stream<List<ReceiptEntity>> receiptStream = receiptRepository.findAll()
.stream()
.collect(Collectors.groupingBy(k -> k.getCocktail().getId()))
.values()
.stream()
.filter(l -> getCountNotHaveIngredient(allowedIngredient, l).equals(iCount));
if (!ingredientFilter.isEmpty()) {
receiptStream = receiptStream.filter(l -> findIngredientInReceipts(ingredientFilter, l));
}
return receiptStream
.map(l -> l.get(0))
.map(ReceiptEntity::getCocktail)
.map(CocktailEntity::getId)
.toList();
}
private boolean findIngredientInReceipts(List<String> ingredientFilter, List<ReceiptEntity> receipts) {
return receipts.stream().anyMatch(r -> ingredientFilter.contains(r.getIngredient().getName()));
}
private Integer getCountNotHaveIngredient(List<Long> allowedIngredientIds, List<ReceiptEntity> receipts) {
return Math.toIntExact(receipts.size() - receipts.stream()
.filter(r -> allowedIngredientIds.contains(r.getIngredient().getId()))
.count());
}
// private List<Long> getAllowedCocktailIds(Long barId) {
// CriteriaBuilder cb = entityManager.getCriteriaBuilder();
// CriteriaQuery<Long> query = cb.createQuery(Long.class);
//
// Root<ReceiptEntity> receiptRoot = query.from(ReceiptEntity.class);
// Join<ReceiptEntity, IngredientEntity> ingredientJoin = receiptRoot.join("ingredient", JoinType.LEFT);
// Join<IngredientEntity, BarEntity> barIngredientStorageJoin = ingredientJoin.join("bars", JoinType.LEFT);
//
// // Внешний подзапрос с NOT EXISTS
// Subquery<Long> subquery = query.subquery(Long.class);
// Root<ReceiptEntity> receiptSubRoot = subquery.from(ReceiptEntity.class);
// Join<ReceiptEntity, IngredientEntity> ingredientSubJoin = receiptSubRoot.join("ingredient", JoinType.LEFT);
//
// // Внутренний подзапрос с NOT EXISTS
// Subquery<Long> innerSubquery = subquery.subquery(Long.class);
// Root<BarIngredientStorage> barIngredientStorageInnerRoot = innerSubquery.from(BarIngredientStorage.class);
//
// // Условия внутреннего подзапроса
// innerSubquery.select(barIngredientStorageInnerRoot.get("id"))
// .where(
// cb.equal(barIngredientStorageInnerRoot.get("ingredient"), ingredientSubJoin.get("id")),
// cb.equal(barIngredientStorageInnerRoot.get("bar").get("id"), barId)
// );
//
// // Условия внешнего подзапроса
// subquery.select(receiptSubRoot.get("id"))
// .where(
// cb.equal(receiptSubRoot.get("cocktail").get("id"), receiptRoot.get("cocktail").get("id")),
// cb.not(cb.exists(innerSubquery))
// );
//
// // Основной запрос
// query.select(receiptRoot.get("cocktail").get("id"))
// .distinct(true)
// .where(
// cb.equal(barIngredientStorageJoin.get("bar").get("id"), barId),
// cb.not(cb.exists(subquery))
// );
//
// return entityManager.createQuery(query).getResultList();
// }
/*
select cifc.cocktail_id
from (select r.cocktail_id, COUNT(CASE WHEN i.is_have THEN 0 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
*/
//todo: так и не придумал я нормальный запрос
private List<Long> findCocktailByCountNotHaveIngredient() {
String sql = "SELECT cifc.cocktail_id" +
" 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);
return query.getResultList();
}
public CocktailForListResponseDto findById(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow();
return mapper.cocktailToFullDto(cocktail);
@@ -267,6 +158,11 @@ public class CocktailService {
.orElseThrow(() -> new RuntimeException("Не удалось найти коктейль с id " + dto.getId()));
}
boolean allowed = dto.getReceipt().stream()
.map(ReceiptResponseDto::getIngredient)
.allMatch(IngredientSimpleResponseDto::getIsHave);
cocktail.setAllowed(allowed);
cocktail.setName(dto.getName());
cocktail.setInstructions(dto.getInstructions());
cocktail.setImage(dto.getImage());
@@ -275,19 +171,66 @@ public class CocktailService {
cocktail.setGlass(Glass.findValue(dto.getGlass()));
cocktail.setAlcoholic(Alcoholic.findValue(dto.getAlcoholic()));
cocktail.setRating(cocktail.getRating());
repository.save(cocktail);
cocktail = repository.save(cocktail);
log.info("{} коктейль {}", dto.getId() == null ? "Создан" : "Изменен", cocktail.getName());
editCocktailReceipts(cocktail.getReceipt(), dto.getReceipt(), cocktail);
}
public void editFavourite(Long cocktailId, boolean put) {
log.info("Коктейль с id {} {}", cocktailId, put ? "добавлен в избранное" : "удален из избранного");
cocktailRepository.updateFavouriteById(cocktailId, put);
}
public void setRating(Long cocktailId, Integer rating) {
log.info("Коктейлю с id {} выставлена новая оценка {}", cocktailId, rating);
cocktailRepository.updateRatingById(cocktailId, rating);
}
public CocktailModalDto getForModal(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
return mapper.cocktailToModalDto(cocktail);
}
public List<CocktailSimpleResponseDto> getSimple() {
return repository.findAll().stream()
.map(CocktailSimpleResponseDto::mapToDto)
.toList();
}
public String savePhoto(MultipartFile file) throws IOException {
File folder = new File(photoFolder);
List<File> files = Arrays.asList(Objects.requireNonNull(folder.listFiles()));
String fileName = getPhotoPath(files, file.getOriginalFilename());
String fullName = photoFolder + "/" + fileName;
file.transferTo(new File(fullName));
log.info("сохранено фото {}", fileName);
return "/assets/cocktails/" + fileName;
}
public void delete(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
log.info("Удален коктейль {}", cocktail);
repository.delete(cocktail);
}
public String findInstructions(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
return cocktail.getInstructions();
}
public List<CocktailForIngredientModalDto> findByIngredient(Long id) {
return ingredientRepository.findById(id).orElseThrow(RuntimeException::new)
.getReceipts()
.stream()
.map(ReceiptEntity::getCocktail)
.distinct()
.map(mapper::cocktailToIngredientDtoList)
.toList();
}
//todo: попробовать отыграть эту связку каскадами
private void editCocktailReceipts(List<ReceiptEntity> old, List<ReceiptResponseDto> actual, CocktailEntity cocktail) {
for (ReceiptResponseDto receipt : actual) {
if (receipt.getId() == null) {
@@ -335,33 +278,6 @@ public class CocktailService {
receiptRepository.save(receiptEntity);
}
public CocktailModalDto getForModal(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
return mapper.cocktailToModalDto(cocktail);
}
public List<ReceiptResponseDto> getReceipts(Long id) {
return null;
}
public List<CocktailSimpleResponseDto> getSimple() {
return repository.findAll().stream()
.map(CocktailSimpleResponseDto::mapToDto)
.toList();
}
public String savePhoto(MultipartFile file) throws IOException {
File folder = new File(photoFolder);
List<File> files = Arrays.asList(Objects.requireNonNull(folder.listFiles()));
String fileName = getPhotoPath(files, file.getOriginalFilename());
String fullName = photoFolder + "/" + fileName;
file.transferTo(new File(fullName));
log.info("сохранено фото {}", fileName);
return "/assets/cocktails/" + fileName;
}
private String getPhotoPath(List<File> files, String originalName) {
if (files.stream().map(File::getName).anyMatch(name -> name.equals(originalName))) {
String[] split = originalName.split("\\.");
@@ -378,25 +294,4 @@ public class CocktailService {
}
return sb.toString();
}
public void delete(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
log.info("Удален коктейль {}", cocktail);
repository.delete(cocktail);
}
public String findInstructions(Long id) {
CocktailEntity cocktail = repository.findById(id).orElseThrow(RuntimeException::new);
return cocktail.getInstructions();
}
public List<CocktailForIngredientModalDto> findByIngredient(Long id) {
return ingredientRepository.findById(id).orElseThrow(RuntimeException::new)
.getReceipts()
.stream()
.map(ReceiptEntity::getCocktail)
.distinct()
.map(mapper::cocktailToIngredientDtoList)
.toList();
}
}

View File

@@ -45,11 +45,13 @@ public class IngredientService {
*/
public List<IngredientResponseDto> getAll() {
List<IngredientEntity> ingredients = repository.findAll();
log.info("По запросу найдено {} ингредиентов", ingredients.size());
return mapper.mapIngredientsToDtoList(ingredients);
}
public List<IngredientSimpleResponseDto> getAllSimple() {
List<IngredientEntity> ingredients = repository.findAll();
log.info("По запросу найдено {} ингредиентов", ingredients.size());
return mapper.mapIngredientsToSimpleDtoList(ingredients);
}
@@ -60,15 +62,31 @@ public class IngredientService {
public void changeBarIngredient(Long id, boolean isHave) {
BarEntity bar = barEntityRepository.findByActiveTrue().orElseThrow();
IngredientEntity ingredientEntity = getIngredientById(id);
if (isHave) {
bar.getIngredients().add(ingredientEntity);
} else {
bar.getIngredients().remove(ingredientEntity);
}
ingredientEntity.setIsHave(isHave);
ingredientRepository.save(ingredientEntity);
List<CocktailEntity> cocktails = ingredientEntity.getReceipts().stream().map(ReceiptEntity::getCocktail).toList();
List<CocktailEntity> listForSave;
if (isHave) {
bar.getIngredients().add(ingredientEntity);
listForSave = new ArrayList<>();
for (CocktailEntity cocktail : cocktails) {
if (cocktail.getReceipt().stream().map(ReceiptEntity::getIngredient).allMatch(IngredientEntity::getIsHave)) {
cocktail.setAllowed(true);
listForSave.add(cocktail);
log.info("Коктейль {} стал доступен", cocktail.getName());
}
}
} else {
bar.getIngredients().remove(ingredientEntity);
listForSave = cocktails.stream().peek(c -> c.setAllowed(false)).toList();
log.info("Коктейли {} пропали из доступа", listForSave);
}
cocktailRepository.saveAll(listForSave);
barEntityRepository.save(bar);
log.info("Ингредиент {} {}", ingredientEntity.getName(), isHave ? "добавлен в бар" : "удален из бара");
}
public boolean saveChange(IngredientResponseDto dto) {
@@ -92,6 +110,7 @@ public class IngredientService {
}
entity.setType(type);
repository.save(entity);
log.info("Ингредиент {} изменен", entity.getName());
return true;
}

View File

@@ -0,0 +1,30 @@
package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.repository.CocktailRepository;
import java.util.List;
@Slf4j
@Service
@RequiredArgsConstructor
public class ReceiptService {
private final CocktailRepository cocktailRepository;
public List<ReceiptResponseDto> getReceiptList(Long cocktailId) {
CocktailEntity cocktail = cocktailRepository.findById(cocktailId).orElseThrow();
return cocktail.getReceipt().stream()
.map(e -> ReceiptResponseDto.builder()
.id(e.getId())
.ingredient(IngredientSimpleResponseDto.mapToDto(e.getIngredient()))
.measure(e.getMeasure())
.build())
.toList();
}
}

View File

@@ -1,89 +0,0 @@
package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
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.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
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.repository.BarEntityRepository;
import ru.kayashov.bar.repository.CocktailRepository;
import ru.kayashov.bar.repository.IngredientRepository;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.List;
import java.util.concurrent.ExecutorService;
@Slf4j
@Service
@RequiredArgsConstructor
public class SessionService {
private final VisitorsRepository visitorsRepository;
private final CocktailRepository cocktailRepository;
private final BarEntityRepository barEntityRepository;
private final IngredientRepository ingredientRepository;
public Visitor getVisitor() {
Long id = ((Visitor) SecurityContextHolder.getContext()
.getAuthentication()
.getPrincipal())
.getId();
return visitorsRepository.findById(id)
.orElseThrow();
}
public List<ReceiptResponseDto> getReceiptList(Long cocktailId) {
CocktailEntity cocktail = cocktailRepository.findById(cocktailId).orElseThrow();
return cocktail.getReceipt().stream()
.map(e -> ReceiptResponseDto.builder()
.id(e.getId())
.ingredient(IngredientSimpleResponseDto.mapToDto(e.getIngredient()))
.measure(e.getMeasure())
.build())
.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);
}
}

View File

@@ -3,20 +3,14 @@ package ru.kayashov.bar.service;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.BarEntityRepository;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.ArrayList;
import java.util.List;
@Service
@RequiredArgsConstructor
public class VisitorService {
private final VisitorsRepository visitorsRepository;
private final BarEntityRepository barRepository;
public Visitor getCurrentVisitor() {
Long id = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
@@ -26,12 +20,4 @@ public class VisitorService {
public Visitor findById(Long id) {
return visitorsRepository.findById(id).orElseThrow(() -> new RuntimeException("Visitor not found. id: " + id));
}
public List<Long> getAllowedIngredients() {
return barRepository.findByActiveTrue().orElseThrow()
.getIngredients()
.stream()
.map(IngredientEntity::getId)
.toList();
}
}

View File

@@ -1,53 +0,0 @@
package ru.kayashov.bar.service.integration.translate;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import ru.kayashov.bar.model.api.translate.Request;
import ru.kayashov.bar.model.api.translate.Response;
import ru.kayashov.bar.model.api.translate.Translate;
import ru.kayashov.bar.service.RestUtil;
import java.util.List;
import java.util.Optional;
@Slf4j
@UtilityClass
public class TranslateService {
private static final String TOKEN = "t1.9euelZrJyoyTmZGQyc2TiZCWlYyLiu3rnpWazsubi8vOzcycms6Znc2dkI7l8_dgXlNC-e9UAyJ4_t3z9yANUUL571QDInj-zef1656Vms2Uio2JmJ6OxpucmoqNjZ6J7_zF656Vms2Uio2JmJ6OxpucmoqNjZ6J.uXSVsrpZcSgQ9qz0-wx6WR79rvq14QCtlC6tnWvah33YRrNqSEBFXBwqMoEq18nG3wHElKE4NsHXK3lxV9SSBQ";
public static String translate(String text) {
return sendTranslate(text)
.map(TranslateService::getTranslateText)
.orElseThrow(RuntimeException::new);
}
public static String softTranslate(String text) {
Optional<ResponseEntity<Response>> opt = sendTranslate(text);
if(opt.isPresent()) {
return TranslateService.getTranslateText(opt.get());
} else {
log.warn("Не удалось перевести текст {}", text);
return text;
}
}
private static Optional<ResponseEntity<Response>> sendTranslate(String text) {
return RestUtil.sendRequest(Response.class,
RequestEntity.post("https://translate.api.cloud.yandex.net/translate/v2/translate")
.header("Authorization", "Bearer " + TOKEN)
.body(new Request(List.of(text))));
}
private static String getTranslateText(ResponseEntity<Response> response) {
Response resp = response.getBody();
StringBuilder sb = new StringBuilder();
List<Translate> translates = resp.getTranslations();
for(Translate translate : translates) {
sb.append(translate.getText());
}
return sb.toString();
}
}