(no commit message provided)
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
package ru.cathub.telegabot.model;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Entity
|
||||
// Указываем имя таблицы и схему из application.properties
|
||||
@Table(name = "bot_settings", schema = "telegabot")
|
||||
public class BotSetting {
|
||||
|
||||
@Id
|
||||
@Column(name = "setting_key", nullable = false, unique = true)
|
||||
private String settingKey; // Ключ настройки (например, "ENABLE_WELCOME_MESSAGE")
|
||||
|
||||
@Column(name = "setting_value", columnDefinition = "TEXT") // Используем TEXT для гибкости
|
||||
private String settingValue; // Значение настройки
|
||||
|
||||
// Можно добавить поле для описания, если нужно
|
||||
// @Column(name = "description")
|
||||
// private String description;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package ru.cathub.telegabot.repository;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
import ru.cathub.telegabot.model.BotSetting;
|
||||
|
||||
@Repository
|
||||
public interface BotSettingRepository extends JpaRepository<BotSetting, String> {
|
||||
// JpaRepository уже предоставляет findById (для получения по ключу), save (для сохранения/обновления), findAll и т.д.
|
||||
// Дополнительные методы пока не требуются.
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package ru.cathub.telegabot.service;
|
||||
|
||||
import ru.cathub.telegabot.exception.ServiceException;
|
||||
import ru.cathub.telegabot.model.BotUser;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public interface BotSettingService {
|
||||
|
||||
/**
|
||||
* Получает значение настройки по ключу.
|
||||
* @param key Ключ настройки.
|
||||
* @return Optional со значением, если найдено, иначе Optional.empty().
|
||||
*/
|
||||
Optional<String> getSettingValue(String key);
|
||||
|
||||
/**
|
||||
* Получает значение настройки по ключу или значение по умолчанию.
|
||||
* @param key Ключ настройки.
|
||||
* @param defaultValue Значение по умолчанию.
|
||||
* @return Значение настройки или defaultValue.
|
||||
*/
|
||||
String getSettingValueOrDefault(String key, String defaultValue);
|
||||
|
||||
/**
|
||||
* Устанавливает значение настройки. Требует прав администратора.
|
||||
* @param key Ключ настройки.
|
||||
* @param value Новое значение.
|
||||
* @param requestingUser Пользователь, выполняющий операцию.
|
||||
* @throws ServiceException если у пользователя нет прав администратора.
|
||||
*/
|
||||
void setSettingValue(String key, String value, BotUser requestingUser) throws ServiceException;
|
||||
|
||||
/**
|
||||
* Получает все настройки в виде Map. Требует прав администратора.
|
||||
* @param requestingUser Пользователь, выполняющий операцию.
|
||||
* @return Map, где ключ - settingKey, значение - settingValue.
|
||||
* @throws ServiceException если у пользователя нет прав администратора.
|
||||
*/
|
||||
Map<String, String> getAllSettings(BotUser requestingUser) throws ServiceException;
|
||||
|
||||
/**
|
||||
* Проверяет, является ли пользователь администратором.
|
||||
* @param user Пользователь для проверки.
|
||||
* @return true, если пользователь администратор, иначе false.
|
||||
*/
|
||||
boolean isAdmin(BotUser user);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package ru.cathub.telegabot.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import ru.cathub.telegabot.exception.ServiceException;
|
||||
import ru.cathub.telegabot.model.BotSetting;
|
||||
import ru.cathub.telegabot.model.BotUser;
|
||||
import ru.cathub.telegabot.repository.BotSettingRepository;
|
||||
import ru.cathub.telegabot.service.BotSettingService;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class BotSettingServiceImpl implements BotSettingService {
|
||||
|
||||
private final BotSettingRepository settingRepository;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true) // Указываем, что метод только для чтения
|
||||
public Optional<String> getSettingValue(String key) {
|
||||
Optional<BotSetting> setting = settingRepository.findById(key);
|
||||
log.trace("Getting setting '{}'. Found: {}", key, setting.isPresent()); // Используем trace для менее важных логов
|
||||
return setting.map(BotSetting::getSettingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true) // Указываем, что метод только для чтения
|
||||
public String getSettingValueOrDefault(String key, String defaultValue) {
|
||||
String value = getSettingValue(key).orElse(defaultValue);
|
||||
log.trace("Getting setting '{}' with default '{}'. Result: '{}'", key, defaultValue, value);
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void setSettingValue(String key, String value, BotUser requestingUser) throws ServiceException {
|
||||
if (!isAdmin(requestingUser)) {
|
||||
log.warn("User {} (ID: {}) attempted to set setting '{}' without admin rights.",
|
||||
requestingUser.getChatId(), requestingUser.getId(), key); // Логируем попытку неавторизованного доступа
|
||||
throw new ServiceException("У вас нет прав для изменения настроек бота.");
|
||||
}
|
||||
|
||||
BotSetting setting = settingRepository.findById(key)
|
||||
.orElse(new BotSetting(key, null)); // Создаем новую, если не найдена
|
||||
|
||||
String oldValue = setting.getSettingValue();
|
||||
log.info("Admin User {} (ID: {}) is setting '{}' from '{}' to '{}'",
|
||||
requestingUser.getChatId(), requestingUser.getId(), key, oldValue, value);
|
||||
|
||||
setting.setSettingValue(value);
|
||||
settingRepository.save(setting);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true) // Указываем, что метод только для чтения
|
||||
public Map<String, String> getAllSettings(BotUser requestingUser) throws ServiceException {
|
||||
if (!isAdmin(requestingUser)) {
|
||||
log.warn("User {} (ID: {}) attempted to list all settings without admin rights.",
|
||||
requestingUser.getChatId(), requestingUser.getId());
|
||||
throw new ServiceException("У вас нет прав для просмотра настроек бота.");
|
||||
}
|
||||
log.debug("Admin User {} (ID: {}) requested all settings.", requestingUser.getChatId(), requestingUser.getId());
|
||||
return settingRepository.findAll().stream()
|
||||
.collect(Collectors.toMap(BotSetting::getSettingKey, setting -> Optional.ofNullable(setting.getSettingValue()).orElse(""))); // Собираем в Map, заменяя null на пустую строку
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAdmin(BotUser user) {
|
||||
// Используем существующее поле UserType
|
||||
boolean isAdmin = user != null && user.getUserType() == BotUser.UserType.ADMIN;
|
||||
log.trace("Checking admin status for user ID {}: {}", user != null ? user.getId() : "null", isAdmin);
|
||||
return isAdmin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Создание таблицы для хранения глобальных настроек бота
|
||||
CREATE TABLE telegabot.bot_settings (
|
||||
setting_key VARCHAR(255) PRIMARY KEY NOT NULL, -- Ключ настройки (уникальный)
|
||||
setting_value TEXT -- Значение настройки (может быть длинным)
|
||||
-- description VARCHAR(1000) -- Опциональное описание настройки
|
||||
);
|
||||
|
||||
-- Добавляем комментарии к таблице и столбцам (для PostgreSQL)
|
||||
COMMENT ON TABLE telegabot.bot_settings IS 'Таблица для хранения глобальных настроек бота';
|
||||
COMMENT ON COLUMN telegabot.bot_settings.setting_key IS 'Уникальный ключ настройки';
|
||||
COMMENT ON COLUMN telegabot.bot_settings.setting_value IS 'Значение настройки';
|
||||
|
||||
-- Добавляем начальное значение для модели AI (рекомендуется)
|
||||
INSERT INTO telegabot.bot_settings (setting_key, setting_value)
|
||||
VALUES ('OPENROUTER_API_MODEL', 'google/gemini-2.5-pro-exp-03-25:free')
|
||||
ON CONFLICT (setting_key) DO NOTHING; -- Не перезаписывать, если ключ уже существует
|
||||
Reference in New Issue
Block a user