Alignement design systeme OK
This commit is contained in:
@@ -0,0 +1,278 @@
|
||||
import 'package:dio/dio.dart';
|
||||
|
||||
import '../../../../core/models/membre_search_criteria.dart';
|
||||
import '../../../../core/models/membre_search_result.dart';
|
||||
|
||||
/// Service pour la recherche avancée de membres
|
||||
/// Gère les appels API vers l'endpoint de recherche sophistiquée
|
||||
class MembreSearchService {
|
||||
final Dio _dio;
|
||||
|
||||
MembreSearchService(this._dio);
|
||||
|
||||
/// Effectue une recherche avancée de membres
|
||||
///
|
||||
/// [criteria] Critères de recherche
|
||||
/// [page] Numéro de page (0-based)
|
||||
/// [size] Taille de la page
|
||||
/// [sortField] Champ de tri
|
||||
/// [sortDirection] Direction du tri (asc/desc)
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les résultats paginés
|
||||
Future<MembreSearchResult> searchMembresAdvanced({
|
||||
required MembreSearchCriteria criteria,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
String sortField = 'nom',
|
||||
String sortDirection = 'asc',
|
||||
}) async {
|
||||
print('Recherche avancée de membres: ${criteria.description}');
|
||||
|
||||
try {
|
||||
// Validation des critères
|
||||
if (!criteria.hasAnyCriteria) {
|
||||
throw Exception('Au moins un critère de recherche doit être spécifié');
|
||||
}
|
||||
|
||||
if (!criteria.isValid) {
|
||||
throw Exception('Critères de recherche invalides');
|
||||
}
|
||||
|
||||
// Préparation des paramètres de requête
|
||||
final queryParams = {
|
||||
'page': page.toString(),
|
||||
'size': size.toString(),
|
||||
'sort': sortField,
|
||||
'direction': sortDirection,
|
||||
};
|
||||
|
||||
// Appel API
|
||||
final response = await _dio.post(
|
||||
'/api/membres/search/advanced',
|
||||
data: criteria.toJson(),
|
||||
queryParameters: queryParams,
|
||||
);
|
||||
|
||||
// Parsing de la réponse
|
||||
final result = MembreSearchResult.fromJson(response.data);
|
||||
|
||||
print('Recherche terminée: ${result.totalElements} résultats en ${result.executionTimeMs}ms');
|
||||
|
||||
return result;
|
||||
} on DioException catch (e) {
|
||||
print('Erreur lors de la recherche avancée: $e');
|
||||
rethrow;
|
||||
} catch (e) {
|
||||
print('Erreur inattendue lors de la recherche: $e');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
/// Recherche rapide par terme général
|
||||
///
|
||||
/// [query] Terme de recherche
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les résultats
|
||||
Future<MembreSearchResult> quickSearch({
|
||||
required String query,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria.quickSearch(query);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche des membres actifs uniquement
|
||||
///
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres actifs
|
||||
Future<MembreSearchResult> searchActiveMembers({
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
return searchMembresAdvanced(
|
||||
criteria: MembreSearchCriteria.activeMembers,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche des membres du bureau
|
||||
///
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres du bureau
|
||||
Future<MembreSearchResult> searchBureauMembers({
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
return searchMembresAdvanced(
|
||||
criteria: MembreSearchCriteria.bureauMembers,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche par organisation
|
||||
///
|
||||
/// [organisationIds] Liste des IDs d'organisations
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres des organisations
|
||||
Future<MembreSearchResult> searchByOrganisations({
|
||||
required List<String> organisationIds,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria(
|
||||
organisationIds: organisationIds,
|
||||
statut: 'ACTIF',
|
||||
);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche par tranche d'âge
|
||||
///
|
||||
/// [ageMin] Âge minimum
|
||||
/// [ageMax] Âge maximum
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres dans la tranche d'âge
|
||||
Future<MembreSearchResult> searchByAgeRange({
|
||||
int? ageMin,
|
||||
int? ageMax,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria(
|
||||
ageMin: ageMin,
|
||||
ageMax: ageMax,
|
||||
statut: 'ACTIF',
|
||||
);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche par région
|
||||
///
|
||||
/// [region] Nom de la région
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres de la région
|
||||
Future<MembreSearchResult> searchByRegion({
|
||||
required String region,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria(
|
||||
region: region,
|
||||
statut: 'ACTIF',
|
||||
);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche par rôles
|
||||
///
|
||||
/// [roles] Liste des rôles
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres ayant ces rôles
|
||||
Future<MembreSearchResult> searchByRoles({
|
||||
required List<String> roles,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria(
|
||||
roles: roles,
|
||||
statut: 'ACTIF',
|
||||
);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Recherche par période d'adhésion
|
||||
///
|
||||
/// [dateMin] Date minimum (ISO 8601)
|
||||
/// [dateMax] Date maximum (ISO 8601)
|
||||
/// [page] Numéro de page
|
||||
/// [size] Taille de la page
|
||||
///
|
||||
/// Returns [MembreSearchResult] avec les membres adhérés dans la période
|
||||
Future<MembreSearchResult> searchByAdhesionPeriod({
|
||||
String? dateMin,
|
||||
String? dateMax,
|
||||
int page = 0,
|
||||
int size = 20,
|
||||
}) async {
|
||||
final criteria = MembreSearchCriteria(
|
||||
dateAdhesionMin: dateMin,
|
||||
dateAdhesionMax: dateMax,
|
||||
statut: 'ACTIF',
|
||||
);
|
||||
return searchMembresAdvanced(
|
||||
criteria: criteria,
|
||||
page: page,
|
||||
size: size,
|
||||
);
|
||||
}
|
||||
|
||||
/// Valide les critères de recherche avant envoi
|
||||
bool validateCriteria(MembreSearchCriteria criteria) {
|
||||
if (!criteria.hasAnyCriteria) {
|
||||
print('Aucun critère de recherche spécifié');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!criteria.isValid) {
|
||||
print('Critères de recherche invalides: ${criteria.description}');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Estime le temps de recherche basé sur les critères
|
||||
Duration estimateSearchTime(MembreSearchCriteria criteria) {
|
||||
// Estimation basique - peut être améliorée avec des métriques réelles
|
||||
int complexityScore = 0;
|
||||
|
||||
if (criteria.query?.isNotEmpty == true) complexityScore += 2;
|
||||
if (criteria.organisationIds?.isNotEmpty == true) complexityScore += 1;
|
||||
if (criteria.roles?.isNotEmpty == true) complexityScore += 1;
|
||||
if (criteria.ageMin != null || criteria.ageMax != null) complexityScore += 1;
|
||||
if (criteria.dateAdhesionMin != null || criteria.dateAdhesionMax != null) complexityScore += 1;
|
||||
|
||||
// Temps de base + complexité
|
||||
final baseTime = 100; // 100ms de base
|
||||
final additionalTime = complexityScore * 50; // 50ms par critère
|
||||
|
||||
return Duration(milliseconds: baseTime + additionalTime);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user