Initial commit

This commit is contained in:
Kayashov.SM
2025-03-12 17:54:16 +04:00
commit b6d8a3cebd
254 changed files with 29963 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyBarApplication {
public static void main(String[] args) {
SpringApplication.run(MyBarApplication.class, args);
}
}

View File

@@ -0,0 +1,15 @@
package ru.kayashov.bar.bot.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Аннотация для пометки команд бота
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface CommandData {
String name();
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.bot.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface FilterTitle {
String title();
}

View File

@@ -0,0 +1,28 @@
package ru.kayashov.bar.bot.config;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.telegram.telegrambots.meta.TelegramBotsApi;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.updatesreceivers.DefaultBotSession;
@Slf4j
@Configuration
@RequiredArgsConstructor
public class TelegramBotConfig {
private final TelegramExecutorBot bot;
@Bean
TelegramBotsApi telegramBotsApi() throws TelegramApiException {
TelegramBotsApi telegramBotsApi = new TelegramBotsApi(DefaultBotSession.class);
try {
telegramBotsApi.registerBot(bot);
} catch (TelegramApiException e) {
log.error("Bot did not register", e);
}
return telegramBotsApi;
}
}

View File

@@ -0,0 +1,41 @@
package ru.kayashov.bar.bot.config;
import org.telegram.telegrambots.meta.api.objects.CallbackQuery;
import org.telegram.telegrambots.meta.api.objects.Chat;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
import ru.kayashov.bar.bot.domain.model.AbstractCallbackQuery;
import ru.kayashov.bar.bot.domain.model.AbstractChat;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboardButton;
import ru.kayashov.bar.bot.domain.model.AbstractMessage;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.List;
public interface TelegramBotMapper {
AbstractUpdate toAbstractUpdate(Update update);
AbstractMessage toAbstractMessage(Message message);
AbstractCallbackQuery toAbstractCallbackQuery(CallbackQuery query);
AbstractChat toAbstractChat(Chat chat);
InlineKeyboardMarkup toInlineKeyboard(AbstractKeyboard replyKeyboard);
ReplyKeyboardMarkup toReplyKeyboard(AbstractKeyboard replyKeyboard);
List<List<InlineKeyboardButton>> toInlineKeyboard(List<List<AbstractKeyboardButton>> buttons);
List<InlineKeyboardButton> toListButtons(List<AbstractKeyboardButton> buttons);
List<KeyboardRow> toKeyboardRows(List<List<AbstractKeyboardButton>> rows);
KeyboardRow toKeyboardRow(List<AbstractKeyboardButton> row);
}

View File

@@ -0,0 +1,128 @@
package ru.kayashov.bar.bot.config;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.objects.CallbackQuery;
import org.telegram.telegrambots.meta.api.objects.Chat;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.KeyboardRow;
import ru.kayashov.bar.bot.domain.model.AbstractCallbackQuery;
import ru.kayashov.bar.bot.domain.model.AbstractChat;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboardButton;
import ru.kayashov.bar.bot.domain.model.AbstractMessage;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.List;
@Component
public class TelegramBotMapperImpl implements TelegramBotMapper {
@Override
public AbstractUpdate toAbstractUpdate(Update update) {
if (update == null) return null;
AbstractUpdate abstractUpdate = new AbstractUpdate();
abstractUpdate.setMessage(toAbstractMessage(update.getMessage()));
abstractUpdate.setCallbackQuery(toAbstractCallbackQuery(update.getCallbackQuery()));
return abstractUpdate;
}
@Override
public AbstractMessage toAbstractMessage(Message message) {
if (message == null) {
return null;
}
AbstractMessage abstractMessage = new AbstractMessage();
abstractMessage.setMessage(message.getText());
abstractMessage.setMessageId(message.getMessageId());
abstractMessage.setChat(toAbstractChat(message.getChat()));
abstractMessage.setChatId(message.getChatId());
return abstractMessage;
}
@Override
public AbstractCallbackQuery toAbstractCallbackQuery(CallbackQuery query) {
if (query == null) {
return null;
}
AbstractCallbackQuery callbackQuery = new AbstractCallbackQuery();
callbackQuery.setData(query.getData());
callbackQuery.setMessage(toAbstractMessage(query.getMessage()));
return callbackQuery;
}
@Override
public AbstractChat toAbstractChat(Chat chat) {
if (chat == null) {
return null;
}
AbstractChat abstractChat = new AbstractChat();
abstractChat.setId(chat.getId());
abstractChat.setFirstName(chat.getFirstName());
abstractChat.setLastName(chat.getLastName());
return abstractChat;
}
@Override
public InlineKeyboardMarkup toInlineKeyboard(AbstractKeyboard replyKeyboard) {
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
inlineKeyboardMarkup.setKeyboard(toInlineKeyboard(replyKeyboard.getKeyboard()));
return inlineKeyboardMarkup;
}
@Override
public ReplyKeyboardMarkup toReplyKeyboard(AbstractKeyboard replyKeyboard) {
return ReplyKeyboardMarkup.builder()
.keyboard(toKeyboardRows(replyKeyboard.getKeyboard()))
.resizeKeyboard(replyKeyboard.getResizeKeyboard())
.inputFieldPlaceholder(replyKeyboard.getInputFieldPlaceholder())
.oneTimeKeyboard(replyKeyboard.getOneTimeKeyboard())
.selective(replyKeyboard.getSelective())
.build();
}
@Override
public List<List<InlineKeyboardButton>> toInlineKeyboard(List<List<AbstractKeyboardButton>> buttons) {
return buttons.stream()
.map(this::toListButtons)
.toList();
}
@Override
public List<InlineKeyboardButton> toListButtons(List<AbstractKeyboardButton> buttons) {
return buttons.stream().map(this::toInlineKeyboardButton).toList();
}
private InlineKeyboardButton toInlineKeyboardButton(AbstractKeyboardButton button) {
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton();
inlineKeyboardButton.setCallbackData(button.getCallbackData());
inlineKeyboardButton.setText(button.getText());
return inlineKeyboardButton;
}
@Override
public List<KeyboardRow> toKeyboardRows(List<List<AbstractKeyboardButton>> rows) {
return rows.stream()
.map(this::toKeyboardRow)
.toList();
}
@Override
public KeyboardRow toKeyboardRow(List<AbstractKeyboardButton> row) {
KeyboardRow keyboardRow = new KeyboardRow();
row.forEach(b -> keyboardRow.add(b.getText()));
return keyboardRow;
}
}

View File

@@ -0,0 +1,17 @@
package ru.kayashov.bar.bot.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "telegram.bot")
public class TelegramBotProperty {
private String username;
private String botToken;
}

View File

@@ -0,0 +1,138 @@
package ru.kayashov.bar.bot.config;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
import org.telegram.telegrambots.meta.api.methods.updatingmessages.DeleteMessage;
import org.telegram.telegrambots.meta.api.objects.Message;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.ReplyKeyboard;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import ru.kayashov.bar.bot.domain.Bot;
import ru.kayashov.bar.bot.domain.command.CommandContainer;
import ru.kayashov.bar.bot.domain.command.api.Command;
import ru.kayashov.bar.bot.domain.methods.AbstractDeleteMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractInlineKeyboard;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.methods.AbstractSendKeyboardMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractSendMessage;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.List;
@Slf4j
@Component
@RequiredArgsConstructor
public class TelegramExecutorBot extends TelegramLongPollingBot implements Bot {
private final TelegramBotMapper mapper;
private final TelegramBotProperty botConfig;
private final CommandContainer commandContainer;
@Override
public String getBotUsername() {
return botConfig.getUsername();
}
@Override
public String getBotToken() {
return botConfig.getBotToken();
}
@Override
public void onUpdateReceived(Update update) {
if (update.hasMessage()) {
Message reply = update.getMessage().getReplyToMessage();
if (reply != null) {
String text = update.getMessage().getText();
String data = "Cocktail:jump:" + text + ":" + reply.getMessageId();
AbstractUpdate message = mapper.toAbstractUpdate(update);
message.getMessage().setMessage(data);
methodExecute(commandContainer.retrieveCommand("Cocktail").execute(message));
return;
}
if (update.hasMessage()) {
String data = update.getMessage().getText();
int dot = data.indexOf(':');
if (dot > -1) {
data = data.substring(0, data.indexOf(":"));
}
methodExecute(commandContainer
.retrieveCommand(data)
.execute(mapper.toAbstractUpdate(update)));
}
} else if (update.hasCallbackQuery() && !update.getCallbackQuery().getData().equals("null")) {
String callbackData = update.getCallbackQuery().getData();
String callbackCommand = callbackData.substring(0, callbackData.indexOf(":"));/*.replace("{\"", "");*/
Command command = commandContainer.retrieveCommand(callbackCommand);
List<? extends AbstractMethod> methods = command.execute(mapper.toAbstractUpdate(update));
methodExecute(methods);
}
}
@Override
public void sendMessage(AbstractSendMessage message) {
SendMessage sendMessage = SendMessage.builder()
.chatId(message.getChatId())
.text(message.getMessage())
.parseMode("HTML")
.build();
try {
execute(sendMessage);
log.info("AbstractMessage successfully sent to chat with id {}", message.getChatId());
} catch (TelegramApiException e) {
log.error("AbstractMessage {} didn't send to chat with id {}", message, message.getChatId(), e);
}
}
@Override
public void sendKeyboardMessage(AbstractSendKeyboardMessage message) {
send(getMessage(message.getChatId(), message.getMessage(), mapper.toReplyKeyboard(message.getKeyboard())));
}
@Override
public void sendInlineKeyboard(AbstractInlineKeyboard message) {
send(getMessage(message.getChatId(), message.getMessage(), mapper.toInlineKeyboard(message.getKeyboard())));
}
@Override
public void deleteMessage(AbstractDeleteMessage message) {
delete(getDeleteMessage(message.getChatId(), message.getMessageId()));
}
private SendMessage getMessage(Long chatId, String message, ReplyKeyboard replyKeyboard) {
return SendMessage.builder()
.chatId(chatId)
.text(message)
.parseMode("HTML")
.replyMarkup(replyKeyboard)
.build();
}
private DeleteMessage getDeleteMessage(Long chatId, Integer messageId) {
return DeleteMessage.builder()
.chatId(chatId)
.messageId(messageId)
.build();
}
private void delete(DeleteMessage abstractDeleteMessage) {
try {
execute(abstractDeleteMessage);
} catch (TelegramApiException e) {
e.printStackTrace();
}
}
private void send(SendMessage sendMessage) {
try {
execute(sendMessage);
log.info("AbstractMessage {} successfully sent to chat with id {}", sendMessage.getText(), sendMessage.getChatId());
} catch (TelegramApiException e) {
log.error("AbstractMessage {} didn't send to chat with id {}", sendMessage.getText(), sendMessage.getChatId(), e);
}
}
}

View File

@@ -0,0 +1,26 @@
package ru.kayashov.bar.bot.domain;
import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import ru.kayashov.bar.bot.domain.methods.AbstractDeleteMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractInlineKeyboard;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.methods.AbstractSendKeyboardMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractSendMessage;
import java.util.List;
public interface Bot {
default void methodExecute(List<? extends AbstractMethod> methods) {
methods.forEach(x -> x.execute(this));
}
void deleteMessage(AbstractDeleteMessage abstractDeleteMessage);
void sendMessage(AbstractSendMessage abstractSendMessage);
void sendKeyboardMessage(AbstractSendKeyboardMessage keyboardMessage);
void sendInlineKeyboard(AbstractInlineKeyboard keyboardMessage);
}

View File

@@ -0,0 +1,52 @@
package ru.kayashov.bar.bot.domain.command;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.annotation.CommandData;
import ru.kayashov.bar.bot.domain.command.api.Command;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Getter
@Component
@RequiredArgsConstructor
public class CommandContainer {
private final List<Command> commandList;
@Qualifier("unknownCommand")
private final Command unknownCommand;
private final Map<String, Command> commandMap = new HashMap<>();
/**
* Метод, собирающий команды, помеченные аннотацией в список
*/
@PostConstruct
private void createCommandMap() throws ClassNotFoundException {
for(Command command : commandList) {
String proxyName = command.getClass().getName();
String className = proxyName.substring(0, proxyName.indexOf("$$"));
String name = Class.forName(className)
.getAnnotation(CommandData.class)
.name();
commandMap.put(name, command);
}
}
/**
* Метод поиска команды
*
* @param commandIdentifier - название команды, пришедшее от пользователя
* @return - Команда бота {@link }, либо сообщение о неизвестной команде
*/
public Command retrieveCommand(String commandIdentifier) {
return commandMap.getOrDefault(commandIdentifier, unknownCommand);
}
}

View File

@@ -0,0 +1,45 @@
package ru.kayashov.bar.bot.domain.command.api;
import org.springframework.transaction.annotation.Transactional;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.model.AbstractCallbackQuery;
import ru.kayashov.bar.bot.domain.model.AbstractMessage;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.List;
public interface Command {
@Transactional
List<? extends AbstractMethod> execute (AbstractUpdate abstractUpdate);
default Long getChatId(AbstractUpdate abstractUpdate) {
AbstractMessage message = abstractUpdate.getMessage();
AbstractCallbackQuery query = abstractUpdate.getCallbackQuery();
if(message != null) {
return message.getChat().getId();
}
if (query != null) {
return query.getMessage().getChatId();
}
throw new RuntimeException("Не возможно найти id чата");
}
default Integer getMessageId(AbstractUpdate abstractUpdate) {
AbstractMessage message = abstractUpdate.getMessage();
AbstractCallbackQuery query = abstractUpdate.getCallbackQuery();
if(message != null) {
return message.getMessageId();
}
if (query != null) {
return query.getMessage().getMessageId();
}
throw new RuntimeException("Не возможно найти id сообщения");
}
}

View File

@@ -0,0 +1,24 @@
package ru.kayashov.bar.bot.domain.command.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.annotation.CommandData;
import ru.kayashov.bar.bot.domain.command.api.Command;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.List;
import static ru.kayashov.bar.bot.domain.utils.MethodUtils.deleteMessage;
@Component
@CommandData(name = "hide")
@RequiredArgsConstructor
public class HideCommand implements Command {
@Override
public List<? extends AbstractMethod> execute(AbstractUpdate abstractUpdate) {
return List.of(deleteMessage(abstractUpdate.getCallbackQuery().getMessage().getChatId(),
abstractUpdate.getCallbackQuery().getMessage().getMessageId()));
}
}

View File

@@ -0,0 +1,49 @@
package ru.kayashov.bar.bot.domain.command.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.annotation.CommandData;
import ru.kayashov.bar.bot.domain.command.api.Command;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.model.AbstractChat;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import static ru.kayashov.bar.bot.domain.utils.MethodUtils.sendMessage;
@Component
@CommandData(name = "\uD83D\uDD11 Вход")
@RequiredArgsConstructor
public class LoginCommand implements Command {
private final VisitorsRepository visitorsRepository;
@Override
public List<? extends AbstractMethod> execute(AbstractUpdate abstractUpdate) {
AbstractChat chat = abstractUpdate.getMessage().getChat();
Random random = new Random();
final Integer code = random.nextInt(1010, 9999);
Optional<Visitor> visitorOpt = visitorsRepository.findById(chat.getId());
if (visitorOpt.isPresent()) {
Visitor visitor = visitorOpt.get();
visitor.setCode(code);
visitorsRepository.save(visitor);
String responseCode = chat.getId() + ":" + code;
responseCode = Base64.getEncoder().encodeToString(responseCode.getBytes());
String message = "Скопируйте код: <code>" + responseCode + "</code> или "
+ "<a href=\"https://bar.kayashov.keenetic.pro/tg?code=" + responseCode
+ "\">перейдите по ссылке</a>";
return List.of(sendMessage(chat.getId(), message));
}
String errorMessage = "Не удалось найти вас в системе. Попробуйте выполнить команду /start";
return List.of(sendMessage(chat.getId(), errorMessage));
}
}

View File

@@ -0,0 +1,60 @@
package ru.kayashov.bar.bot.domain.command.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.telegram.telegrambots.meta.api.methods.GetUserProfilePhotos;
import ru.kayashov.bar.bot.annotation.CommandData;
import ru.kayashov.bar.bot.domain.command.api.Command;
import ru.kayashov.bar.bot.domain.keyboards.reply.ReplyKeyboardMarker;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.model.AbstractChat;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.Base64;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import static ru.kayashov.bar.bot.domain.keyboards.reply.ReplyKeyboardMarker.getMainMenu;
import static ru.kayashov.bar.bot.domain.utils.MethodUtils.sendKeyboardMessage;
import static ru.kayashov.bar.bot.domain.utils.MethodUtils.sendMessage;
/**
* Команда обработки запроса меню
*
* Реализация {@link }
*/
@Component
@CommandData(name="/start")
@RequiredArgsConstructor
public class StartCommand implements Command {
private final VisitorsRepository visitorsRepository;
@Override
public List<? extends AbstractMethod> execute(AbstractUpdate abstractUpdate) {
AbstractChat chat = abstractUpdate.getMessage().getChat();
Optional<Visitor> visitorOpt = visitorsRepository.findById(chat.getId());
String message;
Visitor visitor;
if(visitorOpt.isPresent()) {
visitor = visitorOpt.get();
message = "С возвращением ";
} else {
message = "Спасибо за регистрацию ";
visitor = new Visitor();
visitor.setId(chat.getId());
visitor.setName(chat.getFirstName());
visitor.setLastName(chat.getLastName());
visitor = visitorsRepository.save(visitor);
}
message = message + visitor.getName().strip() +
(visitor.getLastName() != null ? (" " + visitor.getLastName().strip() + "!") : "!");
return List.of(sendKeyboardMessage(chat.getId(), message, getMainMenu()));
}
}

View File

@@ -0,0 +1,27 @@
package ru.kayashov.bar.bot.domain.command.impl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.annotation.CommandData;
import ru.kayashov.bar.bot.domain.command.api.Command;
import ru.kayashov.bar.bot.domain.methods.AbstractMethod;
import ru.kayashov.bar.bot.domain.model.AbstractUpdate;
import java.util.Collections;
import java.util.List;
/**
* Обработка неизвестных команд
* <p>
* Реализация {@link Command}
*/
@Component
@CommandData(name = "unknownCommand")
@RequiredArgsConstructor
public class UnknownCommand implements Command {
@Override
public List<? extends AbstractMethod> execute(AbstractUpdate abstractUpdate) {
return Collections.emptyList();
}
}

View File

@@ -0,0 +1,157 @@
package ru.kayashov.bar.bot.domain.keyboards.inline;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboardButton;
import java.util.ArrayList;
import java.util.List;
/**
* Класс методов для создания инлайн клавиатур
*/
@Component
@RequiredArgsConstructor
public class InlineKeyboardMarker {
/**
* Преобразование списка кнопок в блок основных кнопок
*
* @param sizeRow опциональный размер строки
* @param abstractKeyboardButtons список кнопок для блока
* @return блок основных кнопок
*/
public List<List<AbstractKeyboardButton>> getMainButtons(Integer sizeRow, List<AbstractKeyboardButton> abstractKeyboardButtons) {
// int rowSize = PaginationUtil.getRowSize(sizeRow);
int rowSize = sizeRow;
int rowCountInPage = getRowCount(abstractKeyboardButtons.size(), rowSize);
List<List<AbstractKeyboardButton>> buttons = new ArrayList<>();
for (int row = 0; row < rowCountInPage; row++) {
List<AbstractKeyboardButton> rowButtons = new ArrayList<>(rowSize);
for (int i = 0; i < rowSize; i++) {
int index = (row * rowSize) + i;
if (index >= abstractKeyboardButtons.size()) {
break;
}
rowButtons.add(abstractKeyboardButtons.get(index));
}
buttons.add(rowButtons);
}
return buttons;
}
/**
* Запрос количества строк для основных кнопок
*
* @param elementsOnPage элементов на странице или общее количество
* @param rowSize количество элементов в строке
* @return число строк основных кнопок
*/
private int getRowCount(int elementsOnPage, int rowSize) {
return elementsOnPage / rowSize + (elementsOnPage % rowSize == 0 ? 0 : 1);
}
/**
* Метод создания кнопок пагинации
*
* @return ряд кнопок для пагинации
*/
public List<AbstractKeyboardButton> getPaginationButtons(int index, int total) {
List<AbstractKeyboardButton> buttons = new ArrayList<>();
String pageName = "";
String callback = index != 0 ? "Cocktail:get:" + (index - 1) : "null";
buttons.add(getButtonForPage(callback, pageName));
buttons.add(AbstractKeyboardButton.builder().text(index + 1 + "/" + total).callbackData("null").build());
pageName = "";
callback = index < total - 1 ? "Cocktail:get:" + (index + 1) : "null";
buttons.add(getButtonForPage(callback, pageName));
return buttons;
}
/**
* Метод создания кнопки
*
* @param callBack данные, возвращаемые на сервер
* @param text текст, видимый пользователю
* @return кнопка для вставки в текст
*/
public AbstractKeyboardButton getButtonForPage(String callBack, String text) {
return AbstractKeyboardButton.builder()
.text(text)
.callbackData(callBack)
.build();
}
public static class builder {
private final List<List<AbstractKeyboardButton>> buttons = new ArrayList<>();
private List<List<AbstractKeyboardButton>> mainButtons;
private List<AbstractKeyboardButton> pagination;
private List<AbstractKeyboardButton> back;
private List<AbstractKeyboardButton> hideButton;
private List<AbstractKeyboardButton> stop;
public builder() {
}
public builder buttons(List<List<AbstractKeyboardButton>> buttons) {
this.mainButtons = buttons;
return this;
}
public builder pagination(List<AbstractKeyboardButton> buttons) {
this.pagination = buttons;
return this;
}
public builder backButton(AbstractKeyboardButton button) {
if (button != null)
this.back = List.of(button);
return this;
}
public builder hidden(boolean isActive) {
if (isActive) {
AbstractKeyboardButton button = AbstractKeyboardButton.builder()
.text("Скрыть")
.callbackData("hide:")
.build();
this.hideButton = List.of(button);
}
return this;
}
public builder stopList(boolean isActive, Long cocktailId) {
if (isActive) {
AbstractKeyboardButton button = AbstractKeyboardButton.builder()
.text("Стоп-лист")
.callbackData("Cocktail:stop:" + cocktailId)
.build();
this.stop = List.of(button);
}
return this;
}
public AbstractKeyboard build() {
if (mainButtons != null)
buttons.addAll(mainButtons);
if (pagination != null)
buttons.add(pagination);
if (back != null)
buttons.add(back);
if (hideButton != null)
buttons.add(hideButton);
if (stop != null)
buttons.add(stop);
return AbstractKeyboard.builder().keyboard(buttons).build();
}
}
}

View File

@@ -0,0 +1,37 @@
package ru.kayashov.bar.bot.domain.keyboards.reply;
import lombok.experimental.UtilityClass;
import org.springframework.stereotype.Component;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboardButton;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@UtilityClass
public class ReplyKeyboardMarker {
public static AbstractKeyboard getMainMenu() {
String[] menu;
String mainMenu = "\uD83D\uDD11 Вход";
menu = new String[]{mainMenu/*, " Ингредиенты", "✅ Взять заказ", "💵 Что докупить?"*/};
List<List<AbstractKeyboardButton>> keyboard = getKeyboardRows(menu);
return AbstractKeyboard.builder()
.keyboard(keyboard)
.inputFieldPlaceholder("Меню")
.resizeKeyboard(true)
.selective(true)
.oneTimeKeyboard(false)
.build();
}
private static List<List<AbstractKeyboardButton>> getKeyboardRows(String... buttons) {
return Arrays
.stream(buttons)
.map(x -> List.of(new AbstractKeyboardButton(x)))
.collect(Collectors.toList());
}
}

View File

@@ -0,0 +1,22 @@
package ru.kayashov.bar.bot.domain.methods;
import lombok.Builder;
import lombok.Getter;
import ru.kayashov.bar.bot.domain.Bot;
@Getter
public class AbstractDeleteMessage extends AbstractMethod {
Integer messageId;
@Builder
public AbstractDeleteMessage(Long chatId, Integer messageId) {
super(chatId);
this.messageId = messageId;
}
@Override
public void execute(Bot nBot) {
nBot.deleteMessage(this);
}
}

View File

@@ -0,0 +1,25 @@
package ru.kayashov.bar.bot.domain.methods;
import lombok.Builder;
import lombok.Getter;
import ru.kayashov.bar.bot.domain.Bot;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
@Getter
public class AbstractInlineKeyboard extends AbstractMethod {
private String message;
private AbstractKeyboard keyboard;
@Builder
public AbstractInlineKeyboard(Long chatId, String message, AbstractKeyboard keyboard) {
super(chatId);
this.message = message;
this.keyboard = keyboard;
}
@Override
public void execute(Bot nBot) {
nBot.sendInlineKeyboard(this);
}
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.bot.domain.methods;
import lombok.AllArgsConstructor;
import lombok.Getter;
import ru.kayashov.bar.bot.domain.Bot;
@Getter
@AllArgsConstructor
public abstract class AbstractMethod {
private Long chatId;
public abstract void execute(Bot nBot);
}

View File

@@ -0,0 +1,23 @@
package ru.kayashov.bar.bot.domain.methods;
import lombok.Builder;
import lombok.Getter;
import ru.kayashov.bar.bot.domain.Bot;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
@Getter
public class AbstractSendKeyboardMessage extends AbstractMethod {
String message;
AbstractKeyboard keyboard;
@Builder
public AbstractSendKeyboardMessage(Long chatId, String message, AbstractKeyboard keyboard) {
super(chatId);
this.keyboard = keyboard;
this.message = message;
}
@Override
public void execute(Bot nBot) {
nBot.sendKeyboardMessage(this);
}
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.bot.domain.methods;
import lombok.Builder;
import lombok.Getter;
import ru.kayashov.bar.bot.domain.Bot;
@Getter
public class AbstractSendMessage extends AbstractMethod {
String message;
@Builder
public AbstractSendMessage(Long chatId, String message) {
super(chatId);
this.message = message;
}
public void execute(Bot bot) {
bot.sendMessage(this);
}
}

View File

@@ -0,0 +1,11 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AbstractCallbackQuery {
private AbstractMessage message;
private String data;
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AbstractChat {
private Long id;
private String firstName;
private String lastName;
}

View File

@@ -0,0 +1,16 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.Builder;
import lombok.Data;
import java.util.List;
@Data
@Builder
public class AbstractKeyboard {
private List<List<AbstractKeyboardButton>> keyboard;
private String inputFieldPlaceholder;
private Boolean resizeKeyboard;
private Boolean selective;
private Boolean oneTimeKeyboard;
}

View File

@@ -0,0 +1,21 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AbstractKeyboardButton {
private String text;
private String callbackData;
public AbstractKeyboardButton(String text) {
this.text = text;
}
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AbstractMessage {
private Long chatId;
private Integer messageId;
private String message;
private AbstractChat chat;
}

View File

@@ -0,0 +1,15 @@
package ru.kayashov.bar.bot.domain.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AbstractUpdate {
private AbstractCallbackQuery callbackQuery;
private AbstractMessage message;
public boolean hasMessage() {
return message != null && message.getMessage() != null && !message.getMessage().isEmpty();
}
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonRootName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonRootName(value = "Gen")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CarGenerationDto extends FindServiceDto {
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonRootName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonRootName(value = "Mark")
public class CarMarkDto extends FindServiceDto {
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonRootName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonRootName(value = "Model")
public class CarModelDto extends FindServiceDto {
}

View File

@@ -0,0 +1,21 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonRootName("Find")
public class FindPageableDto {
@JsonProperty("l")
private Long locationId;
@JsonProperty("g")
private Long carGenerationId;
@JsonProperty("p")
private Integer page;
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class FindServiceDto extends PageableDto {
private String name;
private Long value;
private Long old;
}

View File

@@ -0,0 +1,18 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonRootName("Loc")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class LocationDto extends PageableDto {
private Long id;
@JsonProperty("p")
private Long parent;
private String name;
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.bot.domain.model.pojo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PageableDto {
@JsonProperty(value = "pn")
Integer page;
}

View File

@@ -0,0 +1,40 @@
package ru.kayashov.bar.bot.domain.utils;
import ru.kayashov.bar.bot.domain.methods.AbstractDeleteMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractInlineKeyboard;
import ru.kayashov.bar.bot.domain.methods.AbstractSendKeyboardMessage;
import ru.kayashov.bar.bot.domain.methods.AbstractSendMessage;
import ru.kayashov.bar.bot.domain.model.AbstractKeyboard;
public class MethodUtils {
public static AbstractDeleteMessage deleteMessage(Long chatId, Integer messageId) {
return AbstractDeleteMessage.builder()
.messageId(messageId)
.chatId(chatId)
.build();
}
public static AbstractSendMessage sendMessage(Long chatId, String message) {
return AbstractSendMessage.builder()
.message(message)
.chatId(chatId)
.build();
}
public static AbstractSendKeyboardMessage sendKeyboardMessage(Long chatId, String message, AbstractKeyboard keyboard) {
return AbstractSendKeyboardMessage.builder()
.keyboard(keyboard)
.message(message)
.chatId(chatId)
.build();
}
public static AbstractInlineKeyboard sendInlineKeyboard(Long chatId, String message, AbstractKeyboard keyboard) {
return AbstractInlineKeyboard.builder()
.keyboard(keyboard)
.message(message)
.chatId(chatId)
.build();
}
}

View File

@@ -0,0 +1,16 @@
package ru.kayashov.bar.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
public class ExecutorConfig {
@Bean
public ExecutorService executorService() {
return Executors.newFixedThreadPool(3);
}
}

View File

@@ -0,0 +1,86 @@
package ru.kayashov.bar.controller;
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;
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.AuthRequestDto;
import ru.kayashov.bar.controller.dto.AuthResponseDto;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import ru.kayashov.bar.security.JwtTokenProvider;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
@Slf4j
@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
public class AuthController {
private final JwtTokenProvider jwtTokenProvider;
private final VisitorsRepository visitorsRepository;
private final PasswordEncoder passwordEncoder;
@PostMapping("/login")
public AuthResponseDto checkTelegramChat(@RequestBody AuthRequestDto dto) {
if(dto.getByLogin()) {
return checkLogin(dto.getLogin(), dto.getPassword());
} else {
return parseCode(dto.getCode());
}
}
private AuthResponseDto parseCode(String code) {
String decode = new String(Base64.getDecoder().decode(code), StandardCharsets.UTF_8);
String[] decodeArr = decode.split(":");
Visitor visitor = visitorsRepository.findById(Long.valueOf(decodeArr[0]))
.orElseThrow();
Integer visitorCode = visitor.getCode();
if (visitorCode == null) {
return new AuthResponseDto(null, "Повторите запрос кода из бота");
}
if (Integer.valueOf(decodeArr[1]).equals(visitor.getCode())) {
visitor.setCode(null);
visitor = visitorsRepository.save(visitor);
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
}
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();
if(passwordEncoder.matches(password, visitor.getPassword())) {
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
} else {
return new AuthResponseDto(null, "Неверный логин или пароль");
}
}
@PostMapping("refresh")
public AuthResponseDto refreshToken(@RequestHeader("Authorization") String token) {
Claims claims = jwtTokenProvider.extractAllClaims(token);
Long visitorId = claims.get("id", Long.class);
Visitor visitor = visitorsRepository.findById(visitorId).orElseThrow();
return new AuthResponseDto(jwtTokenProvider.generateToken(visitor), null);
}
}

View File

@@ -0,0 +1,142 @@
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.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.bar.BarResponseDto;
import ru.kayashov.bar.controller.dto.bar.CategoryResponseDto;
import ru.kayashov.bar.controller.dto.bar.GlassResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.controller.dto.SessionResponseDto;
import ru.kayashov.bar.controller.dto.bar.TagResponseDto;
import ru.kayashov.bar.controller.dto.VisitorResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.BarResident;
import ru.kayashov.bar.model.entity.SessionEntity;
import ru.kayashov.bar.model.entity.Unit;
import ru.kayashov.bar.model.entity.UnitRepository;
import ru.kayashov.bar.model.entity.UserRole;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.SessionRepository;
import ru.kayashov.bar.repository.TagRepository;
import ru.kayashov.bar.service.SessionService;
import ru.kayashov.bar.service.VisitorService;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/bar/")
@RequiredArgsConstructor
public class BarController {
private final SessionService sessionService;
private final TagRepository tagRepository;
private final SessionRepository sessionRepository;
private final VisitorService visitorService;
private final UnitRepository unitRepository;
@GetMapping("/list")
public List<BarResponseDto> getBarList(@RequestParam Boolean my) {
return sessionService.getBarList(my);
}
@GetMapping("/units")
public List<Unit> getUnitList() {
return unitRepository.findAll();
}
@PostMapping("/addToMyList")
public void addToMyList(@RequestBody BarResponseDto dto) {
sessionService.addToMyList(dto);
}
@PatchMapping("/enter")
public void enterChange(@RequestParam Long id, @RequestParam Boolean value) {
sessionService.enterChange(id, value);
}
@GetMapping("tags")
public List<TagResponseDto> getTags() {
return tagRepository.findAll()
.stream()
.map(TagResponseDto::mapToDto)
.toList();
}
@GetMapping("glass")
public List<GlassResponseDto> getGlass() {
return sessionService.getGlassList().stream()
.map(GlassResponseDto::mapToDto)
.toList();
}
@GetMapping("category")
public List<CategoryResponseDto> getCategory() {
return sessionService.getCategoryList().stream()
.map(CategoryResponseDto::mapToDto)
.toList();
}
@GetMapping("receipt")
public List<ReceiptResponseDto> getReceipt(@RequestParam("id") Long id) {
return sessionService.getReceiptList(id);
}
@GetMapping("session")
public Long getSession() {
return sessionService.findActiveSession().getId();
}
@GetMapping("session/info")
public SessionResponseDto getSessionInfo() {
SessionEntity session = sessionService.findActiveSession();
return SessionResponseDto.mapToDto(session);
}
@PostMapping("session")
public void changeSessionStatus(@RequestParam Boolean value) {
if (value) {
sessionService.createEmptySession();
return;
}
SessionEntity session = sessionService.findActiveSession();
session.setIsActive(false);
sessionRepository.save(session);
}
@GetMapping("/getMe")
public VisitorResponseDto getMe() {
Visitor visitor = visitorService.getCurrentVisitor();
BarResident resident = visitor.getResidents().stream().filter(BarResident::getActive).findFirst().orElse(null);
String role;
Boolean invited;
boolean active;
if(resident != null) {
role = resident.getRole().toString();
invited = resident.getInvited();
active = resident.getBar().getSessions().stream().anyMatch(SessionEntity::getIsActive);
} else {
role = UserRole.USER.toString();
invited = false;
active = false;
}
VisitorResponseDto dto = VisitorResponseDto.mapToDto(visitor, invited, role, active);
log.info("Запрос информации о пользователе: {}-{} {}, {}вошел в бар{},в роли {}",
dto.getId(),
dto.getName().strip(),
dto.getLastName() != null ? dto.getLastName().strip() : "",
invited ? "" : "не ",
resident != null ? " " + resident.getBar().getId() + "-" + resident.getBar().getName() : "",
role);
return dto;
}
}

View File

@@ -0,0 +1,118 @@
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;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.cocktail.CocktailFilterRequestDto;
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 java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/cocktail")
@RequiredArgsConstructor
public class CocktailController {
private final CocktailService cocktailService;
//получить все
@PostMapping("menu")
public List<CocktailForListResponseDto> menu(@RequestBody CocktailFilterRequestDto dto) {
return cocktailService.getMenu(dto);
}
@PostMapping("/photo")
public String savePhoto(@RequestBody MultipartFile file) throws IOException {
if(file == null) {
return "";
}
return cocktailService.savePhoto(file);
}
@GetMapping
public CocktailForListResponseDto getOne(@RequestParam Long id) {
return cocktailService.findById(id);
}
@GetMapping("/simple")
public List<CocktailSimpleResponseDto> getSimple() {
return cocktailService.getSimple();
}
@GetMapping("/receipts")
public List<ReceiptResponseDto> getReceipts(@RequestParam Long id) {
return cocktailService.getReceipts(id);
}
@PostMapping("menuEdit")
public ResponseEntity<ErrorDto> inMenuEdit(@RequestParam Long id, @RequestParam Boolean value) {
try {
cocktailService.inMenuEdit(id, value);
return ResponseEntity.ok(new ErrorDto(null));
} catch (Exception e) {
return ResponseEntity.ok(new ErrorDto(e.getMessage()));
}
}
@GetMapping("/modal")
public CocktailModalDto getForModal(@RequestParam Long id) {
return cocktailService.getForModal(id);
}
@PatchMapping()
public ResponseEntity<ErrorDto> editCocktail(@RequestBody CocktailForListResponseDto dto) {
try {
cocktailService.edit(dto);
return ResponseEntity.ok(new ErrorDto(null));
} catch (Exception e) {
log.error(e.getMessage(), Arrays.toString(e.getStackTrace()));
return ResponseEntity.ok(new ErrorDto(e.getMessage()));
}
}
@DeleteMapping
public void deleteCocktail(@RequestParam Long id) {
cocktailService.delete(id);
}
@PutMapping("/favourite")
public void addInFavourite(@RequestParam("id") Long id) {
Long visitorId = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal())
.getId();
cocktailService.editFavourite(id, visitorId, true);
}
@DeleteMapping("/favourite")
public void deleteFromFavourite(@RequestParam("id") Long id) {
Long visitorId = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal())
.getId();
cocktailService.editFavourite(id, visitorId, false);
}
@PostMapping("/rating")
public void addRating(@RequestParam("id") Long id, @RequestParam("rating") Integer rating) {
cocktailService.setRating(id, rating);
}
}

View File

@@ -0,0 +1,71 @@
package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
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.PatchMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.ingredient.IngredientResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.TypeResponseDto;
import ru.kayashov.bar.repository.TypeRepository;
import ru.kayashov.bar.service.IngredientService;
import java.util.List;
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/ingredient")
@RequiredArgsConstructor
public class IngredientController {
private final IngredientService ingredientService;
private final TypeRepository typeRepository;
@GetMapping("/all")
public List<IngredientResponseDto> getIngredients() {
return ingredientService.getAll();
}
@GetMapping("/simple")
public List<IngredientSimpleResponseDto> getIngredientStringList() {
return ingredientService.getAllSimple();
}
@GetMapping("/type")
public List<TypeResponseDto> getTypes() {
return typeRepository.findAll().stream()
.map(TypeResponseDto::mapToDto)
.toList();
}
@PatchMapping
public ResponseEntity<?> saveChangeForType(@RequestBody IngredientResponseDto dto) {
if(ingredientService.saveChange(dto)) {
return ResponseEntity.ok().build();
} else {
return ResponseEntity.badRequest().build();
}
}
@GetMapping
public IngredientResponseDto getIngredient(@RequestParam Long id) {
return IngredientResponseDto.mapToDto(ingredientService.getIngredientById(id));
}
@DeleteMapping
public void deleteIngredient(@RequestParam Long id) {
ingredientService.changeBarIngredient(id, false);
}
@PutMapping
public void putIngredient(@RequestParam Long id) {
ingredientService.changeBarIngredient(id, true);
}
}

View File

@@ -0,0 +1,82 @@
package ru.kayashov.bar.controller;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
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.bot.domain.Bot;
import ru.kayashov.bar.bot.domain.methods.AbstractSendMessage;
import ru.kayashov.bar.controller.dto.OrderResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.BarResident;
import ru.kayashov.bar.model.entity.SessionEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.service.OrderService;
import ru.kayashov.bar.service.VisitorService;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/order")
@RequiredArgsConstructor
public class OrderController {
private final ExecutorService executor;
private final OrderService orderService;
private final Bot bot;
private final VisitorService visitorService;
@PostMapping
public void pay(@RequestParam Long cocktail) {
Long id = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
List<AbstractSendMessage> messages = orderService.createOrder(id, cocktail);
executor.submit(() -> messages.forEach(bot::sendMessage));
}
@DeleteMapping
public void cancelOrder(@RequestParam Long id) {
AbstractSendMessage message = orderService.updateOrder(false, id);
executor.submit(() -> bot.sendMessage(message));
}
@PutMapping
public void doneOrder(@RequestParam Long id) {
AbstractSendMessage message = orderService.updateOrder(true, id);
executor.submit(() -> bot.sendMessage(message));
}
@GetMapping
public List<OrderResponseDto> getOrders() {
return orderService.getOrders()
.stream()
.map(OrderResponseDto::new)
.toList();
}
@GetMapping("/my")
public List<OrderResponseDto> getMyOrders() {
Visitor visitor = visitorService.getCurrentVisitor();
return visitor.getResidents().stream()
.filter(BarResident::getActive)
.map(BarResident::getBar)
.map(BarEntity::getSessions)
.flatMap(List::stream)
.filter(SessionEntity::getIsActive)
.map(SessionEntity::getOrders)
.flatMap(List::stream)
.filter(o -> Objects.equals(o.getVisitor().getId(), visitor.getId()))
.map(OrderResponseDto::new)
.toList();
}
}

View File

@@ -0,0 +1,36 @@
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.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.repository.VisitorsRepository;
import ru.kayashov.bar.service.VisitorService;
import java.util.List;
import java.util.stream.Stream;
@Slf4j
@CrossOrigin(origins = {"*"})
@RestController
@RequestMapping("/api/visitors")
@RequiredArgsConstructor
public class VisitorController {
private final VisitorService visitorService;
@GetMapping
public List<VisitorResponseDto> getVisitors() {
return visitorService.findAll();
}
@PostMapping("/invite")
public void invite(@RequestParam Boolean value, @RequestParam Long id) {
visitorService.invited(value, id);
}
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.controller.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class AuthRequestDto {
private Boolean byLogin;
private String code;
private String login;
private String password;
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.controller.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public class AuthResponseDto {
private String token;
private String error;
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.controller.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
public class ErrorDto {
private String error;
}

View File

@@ -0,0 +1,24 @@
package ru.kayashov.bar.controller.dto;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.kayashov.bar.controller.dto.cocktail.CocktailSimpleResponseDto;
import ru.kayashov.bar.model.entity.Pay;
@Getter
@Setter
@NoArgsConstructor
public class OrderResponseDto {
private Long id;
private CocktailSimpleResponseDto cocktail;
private VisitorResponseDto visitor;
private String status;
public OrderResponseDto(Pay pay) {
id = pay.getId();
cocktail = CocktailSimpleResponseDto.mapToDto(pay.getCocktail());
visitor = VisitorResponseDto.mapToDto(pay.getVisitor());
status = pay.getStatus().toString();
}
}

View File

@@ -0,0 +1,21 @@
package ru.kayashov.bar.controller.dto;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.SessionEntity;
@Getter
@Setter
public class SessionResponseDto {
private Long id;
private Boolean isActive;
public static SessionResponseDto mapToDto(SessionEntity session) {
SessionResponseDto dto = new SessionResponseDto();
dto.setId(session.getId());
dto.setIsActive(session.getIsActive());
return dto;
}
}

View File

@@ -0,0 +1,37 @@
package ru.kayashov.bar.controller.dto;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.Visitor;
@Getter
@Setter
public class VisitorResponseDto {
private Long id;
private String name;
private String lastName;
private Boolean invited;
private Boolean isActive;
private String role;
public static VisitorResponseDto mapToDto(Visitor e) {
VisitorResponseDto d = new VisitorResponseDto();
d.setId(e.getId());
d.setName(e.getName());
d.setLastName(e.getLastName());
// d.setInvited(e.getInvited());
// d.setRole(e.getRole().toString());
return d;
}
public static VisitorResponseDto mapToDto(Visitor e, Boolean invited, String role, Boolean isActive) {
VisitorResponseDto d = mapToDto(e);
d.setInvited(invited);
d.setRole(role);
d.setIsActive(isActive);
return d;
}
}

View File

@@ -0,0 +1,14 @@
package ru.kayashov.bar.controller.dto.bar;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BarResponseDto {
private Long id;
private String name;
private Boolean open;
private Boolean enter;
private String myRole;
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.controller.dto.bar;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.CategoryEntity;
@Getter
@Setter
public class CategoryResponseDto {
private int id;
private String name;
public static CategoryResponseDto mapToDto(CategoryEntity entity) {
CategoryResponseDto dto = new CategoryResponseDto();
dto.setId(entity.getId());
dto.setName(entity.getName());
return dto;
}
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.controller.dto.bar;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.GlassEntity;
@Getter
@Setter
public class GlassResponseDto {
private int id;
private String name;
public static GlassResponseDto mapToDto(GlassEntity entity) {
GlassResponseDto dto = new GlassResponseDto();
dto.setId(entity.getId());
dto.setName(entity.getName());
return dto;
}
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.controller.dto.bar;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.TagEntity;
@Getter
@Setter
public class TagResponseDto {
private Long id;
private String name;
public static TagResponseDto mapToDto(TagEntity e) {
TagResponseDto dto = new TagResponseDto();
dto.setId(e.getId());
dto.setName(e.getName());
return dto;
}
}

View File

@@ -0,0 +1,27 @@
package ru.kayashov.bar.controller.dto.cocktail;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class CocktailFilterRequestDto {
private String search;
private Boolean onlyFavourite;
private List<String> glass;
private List<String> category;
private List<String> alcohol;
private List<String> tags;
private Integer iCount;
private List<String> ingredient;
private String inMenu;
private SortingEnum sort;
private Boolean all;
private Integer page;
private Integer size;
}

View File

@@ -0,0 +1,91 @@
package ru.kayashov.bar.controller.dto.cocktail;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.Rating;
import ru.kayashov.bar.model.entity.TagEntity;
import java.util.List;
import java.util.stream.Collectors;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CocktailForListResponseDto {
private Long id;
private String name;
private String image;
private String video;
private String instructions;
private Boolean inMenu;
private String category;
private String alcoholic;
private String glass;
private Integer volume;
private Boolean hasError;
private String tags;
private String components;
private Boolean isAllowed;
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.getCategoryEntity().getName());
d.setAlcoholic(e.getAlcoholicEntity().getName());
d.setGlass(e.getGlassEntity().getName());
// d.setIsAllowed(e.getIsAllowed());
d.setTags(e.getTags().stream().map(TagEntity::getName).collect(Collectors.joining(",")));
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();
int sum = 0;
int count = 0;
for (Rating current : e.getRating()) {
//если у данного пользователя есть рейтинг для этого коктейля
if (current.getVisitor().getId().equals(visitorId)) {
//присваиваем избранное для конкретного пользователя
rating.setFavourite(current.isFavorite());
//проверяем, ставил данный пользователь свою оценку этому коктейлю, если да, берем ее и возвращаем рейтинг
if (current.getRating() != 0) {
rating.setRating(current.getRating());
d.setRating(rating);
return d;
}
}
//если пользователь ставил оценку, добавляем ее к сумме остальных оценок и увеличиваем количество оценивших
if (current.getRating() > 0) {
sum += current.getRating();
count++;
}
}
//если после всех итераций есть какая-то сумма оценок - вычисляем среднюю
if (sum > 0) {
rating.setRating(sum / count);
}
d.setRating(rating);
return d;
}
}

View File

@@ -0,0 +1,23 @@
package ru.kayashov.bar.controller.dto.cocktail;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CocktailModalDto {
private Long id;
private String name;
private RatingResponseDto rating;
private String image;
private List<ReceiptResponseDto> receipt;
private String instructions;
}

View File

@@ -0,0 +1,28 @@
package ru.kayashov.bar.controller.dto.cocktail;
import lombok.Getter;
import lombok.Setter;
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.TagEntity;
import java.util.stream.Collectors;
@Getter
@Setter
public class CocktailSimpleResponseDto {
private Long id;
private String name;
private Boolean hasError;
public static CocktailSimpleResponseDto mapToDto(CocktailEntity e) {
CocktailSimpleResponseDto d = new CocktailSimpleResponseDto();
d.setId(e.getId());
d.setName(e.getName());
boolean hasError = e.getReceipt().stream()
.anyMatch(receiptEntity -> receiptEntity.getUnit() == null || receiptEntity.getCount() == null);
d.setHasError(hasError);
return d;
}
}

View File

@@ -0,0 +1,11 @@
package ru.kayashov.bar.controller.dto.cocktail;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class RatingResponseDto {
private int rating = 0;
private boolean favourite = false;
}

View File

@@ -0,0 +1,31 @@
package ru.kayashov.bar.controller.dto.cocktail;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.model.entity.Unit;
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReceiptResponseDto {
private Long id;
private IngredientSimpleResponseDto ingredient;
private String measure;
private Float count;
private Unit unit;
public static ReceiptResponseDto mapToDto(ReceiptEntity e) {
ReceiptResponseDto d = new ReceiptResponseDto();
d.id = e.getId();
d.ingredient = IngredientSimpleResponseDto.mapToDto(e.getIngredient());
d.measure = e.getMeasure();
d.count = e.getCount();
d.unit = e.getUnit();
return d;
}
}

View File

@@ -0,0 +1,32 @@
package ru.kayashov.bar.controller.dto.cocktail;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@Getter
@JsonFormat(shape = JsonFormat.Shape.STRING)
@RequiredArgsConstructor
public enum SortingEnum {
@JsonProperty("name|asc")
NAME_ASC("name", true),
@JsonProperty("name|desc")
NAME_DESC("name", false),
@JsonProperty("rating.rating|desc")
RATING_DESC("rating", false),
@JsonProperty("rating.rating|asc")
RATING_ASC("rating" , true),
@JsonProperty("rating.favourite|desc")
FAVOURITE_DESC("favourite", false),
@JsonProperty("rating.favourite|asc")
FAVOURITE_ASC("favourite", true);
private final String orderBy;
private final Boolean isAsc;
}

View File

@@ -0,0 +1,41 @@
package ru.kayashov.bar.controller.dto.ingredient;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import ru.kayashov.bar.model.entity.IngredientEntity;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IngredientResponseDto {
private Long id;
private String name;
// private String enName;
private Boolean alcohol;
private Integer abv;
private boolean isHave;
private String type;
private String image;
private String description;
public static IngredientResponseDto mapToDto(IngredientEntity i) {
return 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())
.image("https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png")
.description(i.getDescription())
.build();
}
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.controller.dto.ingredient;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.IngredientEntity;
@Getter
@Setter
@AllArgsConstructor
public class IngredientSimpleResponseDto {
private Long id;
private String name;
private Boolean isHave;
public static IngredientSimpleResponseDto mapToDto(IngredientEntity ingredient) {
return new IngredientSimpleResponseDto(ingredient.getId(), ingredient.getName(), false/*ingredient.getIsHave()*/);
}
}

View File

@@ -0,0 +1,19 @@
package ru.kayashov.bar.controller.dto.ingredient;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.entity.TypeEntity;
@Getter
@Setter
public class TypeResponseDto {
private Long id;
private String name;
public static TypeResponseDto mapToDto(TypeEntity e) {
TypeResponseDto dto = new TypeResponseDto();
dto.setId(e.getId());
dto.setName(e.getName());
return dto;
}
}

View File

@@ -0,0 +1,227 @@
package ru.kayashov.bar.mapper;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import ru.kayashov.bar.controller.dto.cocktail.CocktailModalDto;
import ru.kayashov.bar.controller.dto.cocktail.CocktailForListResponseDto;
import ru.kayashov.bar.controller.dto.ingredient.IngredientSimpleResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.RatingResponseDto;
import ru.kayashov.bar.controller.dto.cocktail.ReceiptResponseDto;
import ru.kayashov.bar.model.entity.BarEntity;
import ru.kayashov.bar.model.entity.BarIngredientStorage;
import ru.kayashov.bar.model.entity.BarResident;
import ru.kayashov.bar.model.entity.CocktailEntity;
import ru.kayashov.bar.model.entity.IngredientEntity;
import ru.kayashov.bar.model.entity.Rating;
import ru.kayashov.bar.model.entity.ReceiptEntity;
import ru.kayashov.bar.model.entity.StopList;
import ru.kayashov.bar.model.entity.TagEntity;
import ru.kayashov.bar.model.entity.Visitor;
import ru.kayashov.bar.repository.VisitorsRepository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
@RequiredArgsConstructor
public class CocktailMapper {
private final VisitorsRepository visitorsRepository;
@Transactional
public List<CocktailForListResponseDto> cocktailsToDtoList(List<CocktailEntity> cocktails, Boolean all) {
Visitor visitor = getCurrentVisitor();
// if(checkUserNotInBar(visitor)) {
// return new ArrayList<>();
// }
List<Long> barStopList = getStopList(visitor);
List<Long> allowedIngredients = getAllowedIngredients(visitor);
return cocktails.stream()
.map(c -> cocktailToDto(c, visitor, allowedIngredients, barStopList))
// .filter(c -> all || c.getIsAllowed())
// .filter(c -> all || c.getInMenu())
.toList();
}
public CocktailForListResponseDto cocktailToFullDto(CocktailEntity e) {
List<Long> allowed = getAllowedIngredients(getCurrentVisitor());
return CocktailForListResponseDto.builder()
.id(e.getId())
.name(e.getName())
.image(e.getImage())
.category(e.getCategoryEntity().getName())
.alcoholic(e.getAlcoholicEntity().getName())
.glass(e.getGlassEntity().getName())
.tags(containCocktailTags(e.getTags()))
.instructions(e.getInstructions())
.video(e.getVideo())
.receipt(createReceiptDtoList(e.getReceipt(), allowed))
.build();
}
private boolean checkUserNotInBar(Visitor visitor) {
return visitor.getResidents().stream()
.filter(BarResident::getActive)
.map(BarResident::getBar)
.toList()
.isEmpty();
}
private CocktailForListResponseDto cocktailToDto(CocktailEntity e, Visitor visitor, List<Long> allowedIngredients, List<Long> barStopList) {
boolean hasError = false;
int volume = 0;
Float abv = 0f;
Integer p = null;
for(ReceiptEntity receipt : e.getReceipt()) {
if(receipt.getCount() == null) {
hasError = true;
break;
}
if(receipt.getUnit() == null) {
hasError = true;
break;
}
if(!receipt.getUnit().getId().equals(74L) && abv != null) {
abv = null;
}
if(abv != null) {
IngredientEntity ingredient = receipt.getIngredient();
if(ingredient.getAlcohol() && ingredient.getAbv() == null) {
hasError = true;
break;
}
if(ingredient.getAlcohol()) {
abv += ingredient.getAbv() * receipt.getCount();
}
volume += receipt.getCount();
}
}
if(!hasError && abv != null) {
p = Math.round(abv / volume);
}
return CocktailForListResponseDto.builder()
.id(e.getId())
.name(e.getName())
.image(e.getImage())
.hasError(hasError)
.volume(p)
.category(e.getCategoryEntity().getName())
.alcoholic(e.getAlcoholicEntity().getName())
.glass(e.getGlassEntity().getName())
.tags(containCocktailTags(e.getTags()))
.components(containCocktailComponents(e.getReceipt()))
.rating(createRatingDto(e.getRating(), visitor))
.isAllowed(calculateAllowed(e.getReceipt(), allowedIngredients))
.inMenu(!barStopList.contains(e.getId()))
.build();
// d.setReceipt(e.getReceipt().stream().map(ReceiptResponseDto::mapToDto).toList());
}
private List<Long> getStopList(Visitor visitor) {
return visitor.getResidents().stream()
.filter(BarResident::getActive)
.map(BarResident::getBar)
.map(BarEntity::getStops)
.flatMap(List::stream)
.map(StopList::getCocktail)
.map(CocktailEntity::getId)
.toList();
}
private List<Long> getAllowedIngredients(Visitor visitor) {
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(List<Rating> rating, Visitor visitor) {
RatingResponseDto result = new RatingResponseDto();
int sum = 0;
int count = 0;
for (Rating current : rating) {
if (current.getVisitor().getId().equals(visitor.getId())) {
result.setFavourite(current.isFavorite());
if (current.getRating() != 0) {
result.setRating(current.getRating());
return result;
}
} else if (current.getRating() > 0) {
sum += current.getRating();
count++;
}
}
if (sum > 0) {
result.setRating(sum / count);
}
return result;
}
private String containCocktailComponents(List<ReceiptEntity> receipts) {
return receipts.stream()
.map(ReceiptEntity::getIngredient)
.map(IngredientEntity::getName)
.collect(Collectors.joining(", "));
}
private String containCocktailTags(List<TagEntity> tags) {
return tags.stream()
.map(TagEntity::getName)
.collect(Collectors.joining(","));
}
private Visitor getCurrentVisitor() {
Long visitorId = ((Visitor) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getId();
return visitorsRepository.findById(visitorId).orElseThrow(RuntimeException::new);
}
public CocktailModalDto cocktailToModalDto(CocktailEntity e) {
Visitor visitor = getCurrentVisitor();
List<Long> allowedIngredients = getAllowedIngredients(visitor);
return CocktailModalDto.builder()
.id(e.getId())
.name(e.getName())
.image(e.getImage())
.instructions(e.getInstructions())
.rating(createRatingDto(e.getRating(), visitor))
.receipt(createReceiptDtoList(e.getReceipt(), allowedIngredients))
.build();
}
private List<ReceiptResponseDto> createReceiptDtoList(List<ReceiptEntity> receipts, List<Long> allowedIngredients) {
return receipts.stream()
.map(r -> createReceiptDto(r, allowedIngredients))
.toList();
}
private ReceiptResponseDto createReceiptDto(ReceiptEntity e, List<Long> allowedIngredients) {
return ReceiptResponseDto.builder()
.id(e.getId())
.ingredient(createIngredientResponseDto(e.getIngredient(), allowedIngredients))
.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(), allowedIngredients.contains(i.getId()));
}
}

View File

@@ -0,0 +1,49 @@
package ru.kayashov.bar.mapper;
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.IngredientEntity;
import ru.kayashov.bar.service.VisitorService;
import java.util.List;
@Component
@RequiredArgsConstructor
public class IngredientMapper {
private final VisitorService visitorService;
public List<IngredientResponseDto> mapIngredientsToDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = visitorService.getAllowedIngredients();
return ingredients.stream()
.map(i -> mapIngredientToDto(i, allowedIngredients))
.toList();
}
private IngredientResponseDto mapIngredientToDto(IngredientEntity i, List<Long> allowedIngredients) {
return IngredientResponseDto
.builder()
.id(i.getId())
.name(i.getName())
.alcohol(i.getAlcohol())
.type(i.getType() != null ? i.getType().getName() : null)
.abv(i.getAbv())
.isHave(allowedIngredients.contains(i.getId()))
.image("https://thecocktaildb.com/images/ingredients/" + i.getEnName() + "-Medium.png")
.description(i.getDescription())
.build();
}
public List<IngredientSimpleResponseDto> mapIngredientsToSimpleDtoList(List<IngredientEntity> ingredients) {
List<Long> allowedIngredients = visitorService.getAllowedIngredients();
return ingredients.stream()
.map(i -> mapIngredientToSimpleDto(i, allowedIngredients))
.toList();
}
private IngredientSimpleResponseDto mapIngredientToSimpleDto(IngredientEntity i, List<Long> allowedIngredients) {
return new IngredientSimpleResponseDto(i.getId(), i.getName(), allowedIngredients.contains(i.getId()));
}
}

View File

@@ -0,0 +1,60 @@
package ru.kayashov.bar.model;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class Cocktail {
private String idDrink;
private String strDrink;
private String strDrinkAlternate;
private String strTags;
private String strVideo;
private String strCategory;
private String strIBA;
private String strAlcoholic;
private String strGlass;
private String strInstructions;
private String strDrinkThumb;
private String strImageAttribution;
private String strIngredient1;
private String strIngredient2;
private String strIngredient3;
private String strIngredient4;
private String strIngredient5;
private String strIngredient6;
private String strIngredient7;
private String strIngredient8;
private String strIngredient9;
private String strIngredient10;
private String strIngredient11;
private String strIngredient12;
private String strIngredient13;
private String strIngredient14;
private String strIngredient15;
private String strMeasure1;
private String strMeasure2;
private String strMeasure3;
private String strMeasure4;
private String strMeasure5;
private String strMeasure6;
private String strMeasure7;
private String strMeasure8;
private String strMeasure9;
private String strMeasure10;
private String strMeasure11;
private String strMeasure12;
private String strMeasure13;
private String strMeasure14;
private String strMeasure15;
@Override
public String toString() {
return idDrink + "-" + strDrink + "-" + strAlcoholic;
}
}

View File

@@ -0,0 +1,24 @@
package ru.kayashov.bar.model;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Ingredient {
private String idIngredient;
private String strIngredient;
private String strDescription;
private String strType;
private String strAlcohol;
private String strABV;
@Override
public String toString() {
String mes = idIngredient + "-" + strIngredient;
if(strABV != null) {
mes += "-" + strABV;
}
return mes;
}
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.model.api.cocktail;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.Cocktail;
import java.util.List;
@Getter
@Setter
public class Cocktails {
private List<Cocktail> drinks;
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.model.api.cocktail;
import lombok.Getter;
import lombok.Setter;
import ru.kayashov.bar.model.Ingredient;
import java.util.List;
@Getter
@Setter
public class Ingredients {
private List<Ingredient> ingredients;
}

View File

@@ -0,0 +1,23 @@
package ru.kayashov.bar.model.api.translate;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@NoArgsConstructor
public class Request {
private String sourceLanguageCode = "en";
private String targetLanguageCode = "ru";
private String format = "PLAIN_TEXT";
private String folderId = "b1gugphpvujifrf2gkj5";
private List<String> texts;
private Boolean speller = false;
public Request(List<String> texts) {
this.texts = texts;
}
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.model.api.translate;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
public class Response {
private List<Translate> translations;
}

View File

@@ -0,0 +1,10 @@
package ru.kayashov.bar.model.api.translate;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Translate {
private String text;
}

View File

@@ -0,0 +1,27 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Entity
@Table(name = "alcoholic")
public class AlcoholicEntity {
@Id
private Integer id;
@Column(name = "en_name")
private String enName;
private String name;
@OneToMany(mappedBy = "alcoholicEntity")
private List<CocktailEntity> cocktails;
}

View File

@@ -0,0 +1,35 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;
@Table(name = "bar")
@Entity
@Getter
@Setter
public class BarEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToMany(mappedBy = "bar")
private List<SessionEntity> sessions;
@OneToMany(mappedBy = "bar")
private List<BarIngredientStorage> ingredients;
@OneToMany(mappedBy = "bar")
private List<BarResident> visitors;
@OneToMany(mappedBy = "bar")
private List<StopList> stops;
}

View File

@@ -0,0 +1,28 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
@Getter
@Setter
public class BarIngredientStorage {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private IngredientEntity ingredient;
@ManyToOne
private BarEntity bar;
//todo: с заделом на будущее
private String measure;
}

View File

@@ -0,0 +1,36 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import static ru.kayashov.bar.model.entity.UserRole.USER;
@Entity
@Getter
@Setter
public class BarResident {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private Visitor visitor;
@ManyToOne
private BarEntity bar;
private Boolean invited = true;
private Boolean active = true;
@Enumerated(value = EnumType.STRING)
private UserRole role = USER;
}

View File

@@ -0,0 +1,26 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Entity
@Table(name = "category")
public class CategoryEntity {
@Id
private Integer id;
@Column(name = "en_name")
private String enName;
private String name;
@OneToMany(mappedBy = "categoryEntity")
private List<CocktailEntity> cocktails;
}

View File

@@ -0,0 +1,69 @@
package ru.kayashov.bar.model.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;
@Entity
@Table(name = "cocktail")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class CocktailEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String image;
private String video;
@OneToMany(mappedBy = "cocktail", cascade = CascadeType.REMOVE)
private List<StopList> stopLists;
@Column(columnDefinition = "text")
private String instructions;
@ManyToOne
private CategoryEntity categoryEntity;
@ManyToOne
private AlcoholicEntity alcoholicEntity;
@ManyToOne
private GlassEntity glassEntity;
@OneToMany(mappedBy = "cocktail", cascade = CascadeType.REMOVE)
private List<ReceiptEntity> receipt;
@ManyToMany
@JoinTable(
name = "cocktail_tags",
joinColumns = @JoinColumn(name = "cocktail_id"),
inverseJoinColumns = @JoinColumn(name = "tag_id")
)
private List<TagEntity> tags;
@OneToMany(mappedBy = "cocktail", cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
private List<Rating> rating;
@Override
public String toString() {
return id + "-" + name + "-" + alcoholicEntity.getId();
}
}

View File

@@ -0,0 +1,29 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@Entity
@Table(name = "glass")
public class GlassEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "en_name", nullable = false, length = Integer.MAX_VALUE)
private String enName;
private String name;
@OneToMany(mappedBy = "glassEntity")
private List<CocktailEntity> cocktails;
}

View File

@@ -0,0 +1,48 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Entity
@Table(name = "ingredient")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class IngredientEntity {
@Id
private Long id;
private String name;
private String enName;
private Boolean alcohol;
private Integer abv;
@Column(columnDefinition="text")
private String description;
@OneToMany(mappedBy = "ingredient")
private List<ReceiptEntity> receipts;
@ManyToOne
@JoinColumn(name = "type")
private TypeEntity type;
@OneToMany(mappedBy = "ingredient")
private List<BarIngredientStorage> barIngredients;
}

View File

@@ -0,0 +1,5 @@
package ru.kayashov.bar.model.entity;
public enum OrderStatus {
NEW, PROCESS, DONE, CANCEL;
}

View File

@@ -0,0 +1,24 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import org.springframework.scheduling.annotation.EnableScheduling;
@Entity
@Table(name = "parser")
@Getter
@Setter
public class ParserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private Long ingredientId;
private Long cocktailId;
private Long ingredientError;
private Long cocktailError;
}

View File

@@ -0,0 +1,37 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import java.time.LocalDateTime;
@Entity
@Getter
@Setter
public class Pay {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private CocktailEntity cocktail;
@ManyToOne
private Visitor visitor;
@Enumerated(EnumType.STRING)
private OrderStatus status;
@ManyToOne
private SessionEntity session;
private LocalDateTime createdAt;
private LocalDateTime closedAt;
}

View File

@@ -0,0 +1,30 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
@Getter
@Setter
public class Rating {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private int rating;
private boolean isFavorite;
@ManyToOne
private CocktailEntity cocktail;
@ManyToOne
private Visitor visitor;
}

View File

@@ -0,0 +1,37 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Entity
@Table(name = "receipt")
@Getter
@Setter
public class ReceiptEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private CocktailEntity cocktail;
@ManyToOne
private IngredientEntity ingredient;
private String measure;
private Float count;
@ManyToOne
private Unit unit;
}

View File

@@ -0,0 +1,30 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "session")
public class SessionEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Boolean isActive;
@ManyToOne
private BarEntity bar;
@OneToMany(mappedBy = "session")
private List<Pay> orders;
}

View File

@@ -0,0 +1,26 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
@Entity
@Getter
@Setter
public class StopList {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne
private BarEntity bar;
@ManyToOne
private CocktailEntity cocktail;
}

View File

@@ -0,0 +1,38 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Entity
@Table(name = "tag")
@Getter
@Setter
@NoArgsConstructor
public class TagEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(name = "en_name")
private String enName;
@ManyToMany()
@JoinTable(
name = "cocktail_tags",
inverseJoinColumns = @JoinColumn(name = "cocktail_id"),
joinColumns = @JoinColumn(name = "tag_id")
)
private List<CocktailEntity> cocktails;
}

View File

@@ -0,0 +1,35 @@
package ru.kayashov.bar.model.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "ingredient_type")
@NoArgsConstructor
public class TypeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(name = "en_name")
private String enName;
@OneToMany(mappedBy = "type")
private List<IngredientEntity> ingredients;
public TypeEntity(String enName) {
this.enName = enName;
}
}

View File

@@ -0,0 +1,25 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
@Getter
@Setter
@NoArgsConstructor
public class Unit {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
public Unit(String name) {
this.name = name;
}
}

View File

@@ -0,0 +1,10 @@
package ru.kayashov.bar.model.entity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.Optional;
public interface UnitRepository extends JpaRepository<Unit, Long> {
Optional<Unit> findByName(String unit);
}

View File

@@ -0,0 +1,27 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.Set;
import java.util.stream.Collectors;
@Getter
@RequiredArgsConstructor
public enum UserRole {
USER(Set.of("user")),
BARMEN(Set.of("user", "barmen")),
ADMIN(Set.of("user", "barmen", "admin")),
ADMIN_NOT_BARMEN(Set.of("user", "admin"));
private final Set<String> authorities;
public Set<GrantedAuthority> getAuthorities() {
return authorities.stream()
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toSet());
}
}

View File

@@ -0,0 +1,80 @@
package ru.kayashov.bar.model.entity;
import lombok.Getter;
import lombok.Setter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
@Entity
@Getter
@Setter
public class Visitor implements UserDetails {
@Id
private Long id;
private String name;
private String lastName;
private Integer code;
private String login;
private String password;
private LocalDateTime expired;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "visitor")
private List<Rating> rating;
@OneToMany(mappedBy = "visitor")
private List<BarResident> residents;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return residents.stream()
.filter(BarResident::getActive)
.map(BarResident::getRole)
.map(UserRole::getAuthorities)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return id.toString();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

View File

@@ -0,0 +1,12 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.AlcoholicEntity;
import java.util.Optional;
public interface AlcoholicRepository extends JpaRepository<AlcoholicEntity, Integer> {
Optional<AlcoholicEntity> findByEnNameIgnoreCase(String enName);
Optional<AlcoholicEntity> findByName(String name);
}

View File

@@ -0,0 +1,7 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.BarEntity;
public interface BarEntityRepository extends JpaRepository<BarEntity, Long> {
}

View File

@@ -0,0 +1,7 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.BarIngredientStorage;
public interface BarIngredientStorageRepository extends JpaRepository<BarIngredientStorage, Long> {
}

View File

@@ -0,0 +1,7 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.BarResident;
public interface BarResidentRepository extends JpaRepository<BarResident, Long> {
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.AlcoholicEntity;
import ru.kayashov.bar.model.entity.CategoryEntity;
import java.util.Optional;
public interface CategoryRepository extends JpaRepository<CategoryEntity, Integer> {
Optional<CategoryEntity> findByEnNameIgnoreCase(String enName);
Optional<CategoryEntity> findByNameIgnoreCase(String name);
}

View File

@@ -0,0 +1,10 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.CocktailEntity;
import java.util.Collection;
import java.util.List;
public interface CocktailRepository extends JpaRepository<CocktailEntity, Long> {
}

View File

@@ -0,0 +1,13 @@
package ru.kayashov.bar.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import ru.kayashov.bar.model.entity.AlcoholicEntity;
import ru.kayashov.bar.model.entity.GlassEntity;
import java.util.Optional;
public interface GlassRepository extends JpaRepository<GlassEntity, Integer> {
Optional<GlassEntity> findByEnNameIgnoreCase(String enName);
Optional<GlassEntity> findByNameIgnoreCase(String enName);
}

Some files were not shown because too many files have changed in this diff Show More