import 'dart:async'; import 'package:fikoyt_akcali_v1/apps/finans/core/models/finans.model.dart'; import 'package:fikoyt_akcali_v1/apps/finans/core/services/finans.servis.dart'; import 'package:fikoyt_ui/fikoyt_ui.dart'; import 'package:isar/isar.dart'; // 🎯 Gelişmiş Isar + GetX servis yapısı // Özellikler: // - Generic Collection desteği // - Stream ile canlı güncellemeler // - Daha Fazla Göster desteği // - Arama & Sıralama desteği // - CRUD işlemleri // - Sayfalama cache // - İlişkisel yüklemeler // - Yetki denetimi // - Toplu ekle/güncelle // - Manuel veri çekme (getList) import 'dart:async'; import 'package:get/get.dart'; import 'package:isar/isar.dart'; abstract class IsarFullService extends GetxService { late Isar isar; // 🔁 Reactive Liste RxList liste = [].obs; RxBool yukleniyor = false.obs; RxBool hepsiYuklendi = false.obs; RxInt sayi = 3.obs; RxInt limit = 3.obs; RxInt offset = 0.obs; RxString aramaMetni = ''.obs; RxString? siralamaAlani = RxString(''); RxBool siralamaTers = false.obs; RxInt veriSayisi = 0.obs; // 📦 Sayfalama Cache // final Map> sayfaCache = {}; // 🔌 Stream aboneliği StreamSubscription>? _subscription; // ✅ Giriş yapan kullanıcı varsa buradan kontrol edilebilir dynamic get aktifKullanici => null; // override edilerek yetki eklenebilir // === ABSTRACT === Isar getIsar(); IsarCollection get koleksiyon; QueryBuilder getQuery(); // 🔍 Arama filtresi (override edilebilir) QueryBuilder applyAramaFiltre(QueryBuilder q, String arama) { return q; } // 🔁 Dinamik sıralama fonksiyon haritası (override edilebilir) Map Function(QueryBuilder, bool)> getSiralamaFonksiyonlari() { return {}; } // ⬆️ Sıralama filtresi (override edilebilir) QueryBuilder applySiralama(QueryBuilder q) { final siralama = siralamaAlani?.value ?? ''; final ters = siralamaTers.value; final fonksiyonlar = getSiralamaFonksiyonlari(); if (siralama.isNotEmpty && fonksiyonlar.containsKey(siralama)) { return fonksiyonlar[siralama]!(q, ters); } return q; } // 🔗 İlişkisel yükleme (override edilebilir) Future iliskileriYukle(List liste) async {} @override void onInit() { super.onInit(); isar = getIsar(); _veriyiIzle(); ilkYukleme(); } Future _veriyiIzle() async { await _subscription?.cancel(); final q = applySiralama(applyAramaFiltre(getQuery(), aramaMetni.value)); _subscription = q.watch(fireImmediately: true).listen((veriler) async { final gosterilecek = veriler.take(offset.value).toList(); await iliskileriYukle(gosterilecek); liste.value = RxList(gosterilecek); hepsiYuklendi.value = gosterilecek.length >= veriler.length; }); veriSayisi.value = await q.count(); } Future ilkYukleme() async { offset.value = limit.value; hepsiYuklendi.value = false; // sayfaCache.clear(); await dahaFazla(); } bool get dahaAzGoster { return liste.length > sayi.value * 2; } Future dahaAz() async { yukleniyor.value = true; offset.value = liste.length - sayi.value; if (offset.value < sayi.value) offset.value = sayi.value; // liste.clear(); hepsiYuklendi.value = false; // sayfaCache.clear(); _veriyiIzle(); yukleniyor.value = false; } bool get dahaSifirlaGoster { return liste.length > sayi.value * 4; } Future dahaSifirla() async { yukleniyor.value = true; offset.value = sayi.value; // liste.clear(); hepsiYuklendi.value = false; // sayfaCache.clear(); _veriyiIzle(); yukleniyor.value = false; } bool get dahaFazlaGoster { return veriSayisi.value > liste.length; } Future dahaFazla() async { if (yukleniyor.value || hepsiYuklendi.value) return; yukleniyor.value = true; // final sayfaNo = (liste.length / sayi.value).floor(); // if (sayfaCache.containsKey(sayfaNo)) { // liste.addAll(sayfaCache[sayfaNo]!); // yukleniyor.value = false; // return; // } final q = applySiralama(applyAramaFiltre(getQuery(), aramaMetni.value)).offset(liste.length).limit(sayi.value); final yeniVeri = await q.findAll(); await iliskileriYukle(yeniVeri); // sayfaCache[sayfaNo] = yeniVeri; liste.addAll(yeniVeri); if (yeniVeri.length < sayi.value) hepsiYuklendi.value = true; offset.value = liste.length; yukleniyor.value = false; } Future listeyiYenile() async { yukleniyor.value = true; offset.value = liste.length; liste.clear(); hepsiYuklendi.value = false; // sayfaCache.clear(); _veriyiIzle(); yukleniyor.value = false; } // Arama debounce timer Timer? debounceTimer; void aramaYap(String yeniMetin) { debounceTimer?.cancel(); // Önceki varsa iptal et debounceTimer = Timer(const Duration(milliseconds: 300), () { aramaMetni.value = yeniMetin; listeyiYenile(); }); } void siralamaAyarla(String alan, {bool ters = false}) { siralamaAlani?.value = alan; siralamaTers.value = ters; listeyiYenile(); } /// Manuel veri çekmek isteyenler için Future> getList({ int? offset, int? limit, String? arama, String? siralama, bool siralamaTers = false, bool iliskileriYukle = true, }) async { var q = getQuery(); if (arama != null && arama.isNotEmpty) { q = applyAramaFiltre(q, arama); } final fonksiyonlar = getSiralamaFonksiyonlari(); if (siralama != null && siralama.isNotEmpty && fonksiyonlar.containsKey(siralama)) { q = fonksiyonlar[siralama]!(q, siralamaTers); } if (offset != null) q = q.offset(offset) as QueryBuilder; if (limit != null) q = q.limit(limit) as QueryBuilder; final sonuc = await q.findAll(); if (iliskileriYukle) await this.iliskileriYukle(sonuc); return sonuc; } // === CRUD === Future beforeEkle(T item) async { return item; } Future ekle(T item) async { await isar.writeTxn(() async { item = await beforeEkle(item); await koleksiyon.put(item); await afterEkle(item); }); await listeyiYenile(); } Future afterEkle(T item) async { return; } Future guncelle(T item) async { await isar.writeTxn(() => koleksiyon.put(item)); await listeyiYenile(); } Future sil(Id id) async { await isar.writeTxn(() => koleksiyon.delete(id)); await listeyiYenile(); } Future getir(Id id) async { return await koleksiyon.get(id); } Future topluEkle(List veri) async { await isar.writeTxn(() async { await koleksiyon.putAll(veri); }); await listeyiYenile(); } Future topluGuncelle(List veri) async { await isar.writeTxn(() async { await koleksiyon.putAll(veri); }); await listeyiYenile(); } @override void onClose() { _subscription?.cancel(); super.onClose(); } }