Adds SMS handler settings to Hive
Adds the necessary classes and configurations to store and retrieve SMS handler settings using Hive database. This includes registering the `SmsHandlerSettings` model, its adapter, and related enum adapters with Hive, opening a new box for storing settings and making it accessible via `HiveService`. Additionally, this change registers a new repository for accessing sms handler settings data.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import 'package:budget_app/hive/hive_registrar.g.dart';
|
||||
import 'package:budget_app/models/app_settings.dart'; // Добавлен импорт AppSettings
|
||||
import 'package:budget_app/models/global_settings.dart';
|
||||
import 'package:budget_app/models/sms_handler_settings.dart';
|
||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
@@ -21,6 +22,7 @@ class HiveService {
|
||||
static const String _userBox = 'users';
|
||||
static const String _smsMessageBox = 'smsMessages';
|
||||
static const String _globalSettings = 'global_settings';
|
||||
static const String _smsHandlerSettingsBox = 'sms_handler_settings';
|
||||
|
||||
static Future<void> init() async {
|
||||
_logger.i('Initializing Hive database');
|
||||
@@ -39,6 +41,7 @@ class HiveService {
|
||||
Hive.openBox<User>(_userBox),
|
||||
Hive.openBox<SmsMessage>(_smsMessageBox),
|
||||
Hive.openBox<GlobalSettings>(_globalSettings),
|
||||
Hive.openBox<SmsHandlerSettings>(_smsHandlerSettingsBox),
|
||||
]);
|
||||
|
||||
// Проверка и заполнение начальными данными
|
||||
@@ -56,6 +59,8 @@ class HiveService {
|
||||
Hive.box<SmsMessage>(_smsMessageBox);
|
||||
static Box<GlobalSettings> get globalSettings =>
|
||||
Hive.box<GlobalSettings>(_globalSettings);
|
||||
static Box<SmsHandlerSettings> get smsHandlerSettings =>
|
||||
Hive.box<SmsHandlerSettings>(_smsHandlerSettingsBox);
|
||||
|
||||
/// Проверяет и заполняет боксы начальными данными при первом запуске
|
||||
static void _checkAndFillInitialData() {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:hive_ce/hive.dart';
|
||||
|
||||
import '../../models/sms_handler_settings.dart';
|
||||
import 'interfaces/isms_handler_repository.dart';
|
||||
|
||||
/// Реализация репозитория для настроек обработки СМС с использованием Hive.
|
||||
class HiveSmsHandlerRepository implements ISmsHandlerRepository {
|
||||
final Box<SmsHandlerSettings> _smsHandlerBox;
|
||||
|
||||
HiveSmsHandlerRepository(this._smsHandlerBox);
|
||||
|
||||
@override
|
||||
Future<SmsHandlerSettings?> getSmsHandlerSettings(String userId) async {
|
||||
// В Hive мы будем использовать ID пользователя как ключ для его настроек.
|
||||
return _smsHandlerBox.get(userId);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> saveSmsHandlerSettings(SmsHandlerSettings settings) async {
|
||||
// Сохраняем объект настроек по ключу, равному ID пользователя.
|
||||
await _smsHandlerBox.put(settings.userId, settings);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> saveRuleForSender(String userId, String sender, SmsProcessingRule rule) async {
|
||||
// 1. Получаем текущие настройки.
|
||||
SmsHandlerSettings? settings = await getSmsHandlerSettings(userId);
|
||||
|
||||
if (settings == null) {
|
||||
// 2. Если настроек нет, создаем новый объект.
|
||||
settings = SmsHandlerSettings(
|
||||
userId: userId,
|
||||
rulesBySender: {sender: rule}, // Создаем карту с первым правилом
|
||||
);
|
||||
} else {
|
||||
// 3. Если настройки есть, обновляем или добавляем правило.
|
||||
settings.rulesBySender[sender] = rule;
|
||||
}
|
||||
|
||||
// 4. Сохраняем обновленный объект настроек.
|
||||
await saveSmsHandlerSettings(settings);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deleteRuleForSender(String userId, String sender) async {
|
||||
// 1. Получаем текущие настройки.
|
||||
final settings = await getSmsHandlerSettings(userId);
|
||||
|
||||
if (settings != null) {
|
||||
// 2. Если настройки существуют, удаляем правило для отправителя.
|
||||
settings.rulesBySender.remove(sender);
|
||||
// 3. Сохраняем измененный объект.
|
||||
await saveSmsHandlerSettings(settings);
|
||||
}
|
||||
// Если настроек нет, ничего не делаем.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import '../../../models/sms_handler_settings.dart';
|
||||
|
||||
/// Абстрактный класс (интерфейс) для репозитория настроек обработки СМС.
|
||||
/// Определяет контракт, по которому UI и бизнес-логика будут взаимодействовать
|
||||
/// с данными о настройках, не зная деталей их реализации (Hive, Firebase, etc).
|
||||
abstract class ISmsHandlerRepository {
|
||||
/// Получает настройки обработки СМС для указанного пользователя.
|
||||
///
|
||||
/// [userId] - Уникальный идентификатор пользователя.
|
||||
/// Возвращает [SmsHandlerSettings] или null, если настроек нет.
|
||||
Future<SmsHandlerSettings?> getSmsHandlerSettings(String userId);
|
||||
|
||||
/// Сохраняет или обновляет настройки обработки СМС для пользователя.
|
||||
///
|
||||
/// [settings] - Объект с настройками, который нужно сохранить.
|
||||
Future<void> saveSmsHandlerSettings(SmsHandlerSettings settings);
|
||||
|
||||
/// Добавляет или обновляет правило для конкретного отправителя.
|
||||
///
|
||||
/// [userId] - ID пользователя.
|
||||
/// [sender] - Идентификатор отправителя (например, 'SBERBANK').
|
||||
/// [rule] - Правило обработки.
|
||||
Future<void> saveRuleForSender(String userId, String sender, SmsProcessingRule rule);
|
||||
|
||||
/// Удаляет правило для конкретного отправителя.
|
||||
///
|
||||
/// [userId] - ID пользователя.
|
||||
/// [sender] - Идентификатор отправителя, чье правило нужно удалить.
|
||||
Future<void> deleteRuleForSender(String userId, String sender);
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'package:budget_app/hive/hive_adapters.dart';
|
||||
import 'package:budget_app/models/app_settings.dart';
|
||||
import 'package:budget_app/models/category.dart';
|
||||
import 'package:budget_app/models/global_settings.dart';
|
||||
import 'package:budget_app/models/sms_handler_settings.dart';
|
||||
import 'package:budget_app/models/sms_message.dart';
|
||||
import 'package:budget_app/models/tag.dart';
|
||||
import 'package:budget_app/models/transaction_record.dart';
|
||||
@@ -19,7 +20,10 @@ extension HiveRegistrar on HiveInterface {
|
||||
registerAdapter(ColorAdapter());
|
||||
registerAdapter(GlobalSettingsAdapter());
|
||||
registerAdapter(IconDataAdapter());
|
||||
registerAdapter(SmsHandlerSettingsAdapter());
|
||||
registerAdapter(SmsMessageAdapter());
|
||||
registerAdapter(SmsProcessingRuleAdapter());
|
||||
registerAdapter(SmsProcessingTypeAdapter());
|
||||
registerAdapter(TagAdapter());
|
||||
registerAdapter(TransactionRecordAdapter());
|
||||
registerAdapter(UserAdapter());
|
||||
@@ -33,7 +37,10 @@ extension IsolatedHiveRegistrar on IsolatedHiveInterface {
|
||||
registerAdapter(ColorAdapter());
|
||||
registerAdapter(GlobalSettingsAdapter());
|
||||
registerAdapter(IconDataAdapter());
|
||||
registerAdapter(SmsHandlerSettingsAdapter());
|
||||
registerAdapter(SmsMessageAdapter());
|
||||
registerAdapter(SmsProcessingRuleAdapter());
|
||||
registerAdapter(SmsProcessingTypeAdapter());
|
||||
registerAdapter(TagAdapter());
|
||||
registerAdapter(TransactionRecordAdapter());
|
||||
registerAdapter(UserAdapter());
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import 'package:budget_app/data/repositories/hive_sms_handler_repository.dart';
|
||||
import 'package:budget_app/data/repositories/hive_sms_message_repository.dart';
|
||||
import 'package:budget_app/data/repositories/interfaces/isms_handler_repository.dart';
|
||||
import 'package:budget_app/data/repositories/interfaces/isms_message_repository.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
|
||||
@@ -54,6 +56,10 @@ Future<void> initDependencies() async {
|
||||
HiveGlobalSettingsRepository(HiveService.globalSettings),
|
||||
);
|
||||
|
||||
getIt.registerSingleton<ISmsHandlerRepository>(
|
||||
HiveSmsHandlerRepository(HiveService.smsHandlerSettings),
|
||||
);
|
||||
|
||||
// Services
|
||||
getIt.registerSingleton<SmsService>(SmsService());
|
||||
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
import 'package:hive_ce/hive.dart';
|
||||
|
||||
part 'sms_handler_settings.g.dart';
|
||||
|
||||
/// Перечисление для определения типа обработки СМС.
|
||||
@HiveType(typeId: 10)
|
||||
enum SmsProcessingType {
|
||||
/// Обработка с использованием регулярного выражения.
|
||||
@HiveField(0)
|
||||
regexp,
|
||||
|
||||
/// Обработка с использованием кастомной функции.
|
||||
@HiveField(1)
|
||||
customFunction,
|
||||
}
|
||||
|
||||
/// Модель для хранения правила обработки СМС от конкретного отправителя.
|
||||
@HiveType(typeId: 11)
|
||||
class SmsProcessingRule extends HiveObject {
|
||||
/// Тип обработки (regexp или кастомная функция).
|
||||
@HiveField(0)
|
||||
final SmsProcessingType type;
|
||||
|
||||
/// Шаблон регулярного выражения (используется, если type == SmsProcessingType.regexp).
|
||||
@HiveField(1)
|
||||
final String? pattern;
|
||||
|
||||
/// Идентификатор кастомной функции (используется, если type == SmsProcessingType.customFunction).
|
||||
/// В коде этот ID будет сопоставляться с реальной функцией.
|
||||
@HiveField(2)
|
||||
final String? customFunctionId;
|
||||
|
||||
SmsProcessingRule({
|
||||
required this.type,
|
||||
this.pattern,
|
||||
this.customFunctionId,
|
||||
}) : assert(
|
||||
(type == SmsProcessingType.regexp && pattern != null) ||
|
||||
(type == SmsProcessingType.customFunction && customFunctionId != null),
|
||||
'Pattern must be provided for regexp type, and customFunctionId for customFunction type.',
|
||||
);
|
||||
}
|
||||
|
||||
/// Модель для хранения всех настроек обработки СМС для одного пользователя.
|
||||
@HiveType(typeId: 12)
|
||||
class SmsHandlerSettings extends HiveObject {
|
||||
/// Уникальный идентификатор пользователя, к которому относятся эти настройки.
|
||||
@HiveField(0)
|
||||
final String userId;
|
||||
|
||||
/// Карта правил обработки, где ключ - это идентификатор отправителя (например, 'SBERBANK' или номер телефона),
|
||||
/// а значение - правило обработки для этого отправителя.
|
||||
@HiveField(1)
|
||||
final Map<String, SmsProcessingRule> rulesBySender;
|
||||
|
||||
SmsHandlerSettings({
|
||||
required this.userId,
|
||||
required this.rulesBySender,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'sms_handler_settings.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// TypeAdapterGenerator
|
||||
// **************************************************************************
|
||||
|
||||
class SmsProcessingRuleAdapter extends TypeAdapter<SmsProcessingRule> {
|
||||
@override
|
||||
final typeId = 11;
|
||||
|
||||
@override
|
||||
SmsProcessingRule read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return SmsProcessingRule(
|
||||
type: fields[0] as SmsProcessingType,
|
||||
pattern: fields[1] as String?,
|
||||
customFunctionId: fields[2] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SmsProcessingRule obj) {
|
||||
writer
|
||||
..writeByte(3)
|
||||
..writeByte(0)
|
||||
..write(obj.type)
|
||||
..writeByte(1)
|
||||
..write(obj.pattern)
|
||||
..writeByte(2)
|
||||
..write(obj.customFunctionId);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SmsProcessingRuleAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
|
||||
class SmsHandlerSettingsAdapter extends TypeAdapter<SmsHandlerSettings> {
|
||||
@override
|
||||
final typeId = 12;
|
||||
|
||||
@override
|
||||
SmsHandlerSettings read(BinaryReader reader) {
|
||||
final numOfFields = reader.readByte();
|
||||
final fields = <int, dynamic>{
|
||||
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
|
||||
};
|
||||
return SmsHandlerSettings(
|
||||
userId: fields[0] as String,
|
||||
rulesBySender: (fields[1] as Map).cast<String, SmsProcessingRule>(),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SmsHandlerSettings obj) {
|
||||
writer
|
||||
..writeByte(2)
|
||||
..writeByte(0)
|
||||
..write(obj.userId)
|
||||
..writeByte(1)
|
||||
..write(obj.rulesBySender);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SmsHandlerSettingsAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
|
||||
class SmsProcessingTypeAdapter extends TypeAdapter<SmsProcessingType> {
|
||||
@override
|
||||
final typeId = 10;
|
||||
|
||||
@override
|
||||
SmsProcessingType read(BinaryReader reader) {
|
||||
switch (reader.readByte()) {
|
||||
case 0:
|
||||
return SmsProcessingType.regexp;
|
||||
case 1:
|
||||
return SmsProcessingType.customFunction;
|
||||
default:
|
||||
return SmsProcessingType.regexp;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void write(BinaryWriter writer, SmsProcessingType obj) {
|
||||
switch (obj) {
|
||||
case SmsProcessingType.regexp:
|
||||
writer.writeByte(0);
|
||||
case SmsProcessingType.customFunction:
|
||||
writer.writeByte(1);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => typeId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is SmsProcessingTypeAdapter &&
|
||||
runtimeType == other.runtimeType &&
|
||||
typeId == other.typeId;
|
||||
}
|
||||
Reference in New Issue
Block a user