205 lines
5.5 KiB
Dart
205 lines
5.5 KiB
Dart
import 'dart:async';
|
|
import 'dart:io';
|
|
import 'package:dio/dio.dart';
|
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:geosector_app/core/data/models/user_model.dart';
|
|
import 'package:geosector_app/core/constants/app_keys.dart';
|
|
import 'package:retry/retry.dart';
|
|
|
|
class ApiService {
|
|
final Dio _dio = Dio();
|
|
final String _baseUrl = AppKeys.baseApiUrl;
|
|
String? _sessionId;
|
|
|
|
ApiService() {
|
|
_dio.options.baseUrl = _baseUrl;
|
|
_dio.options.connectTimeout = AppKeys.connectionTimeout;
|
|
_dio.options.receiveTimeout = AppKeys.receiveTimeout;
|
|
_dio.options.headers.addAll(AppKeys.defaultHeaders);
|
|
|
|
// Ajouter des intercepteurs pour l'authentification par session
|
|
_dio.interceptors.add(InterceptorsWrapper(onRequest: (options, handler) {
|
|
// Ajouter le session_id comme token Bearer aux en-têtes si disponible
|
|
if (_sessionId != null) {
|
|
options.headers[AppKeys.sessionHeader] = 'Bearer $_sessionId';
|
|
}
|
|
return handler.next(options);
|
|
}, onError: (DioException error, handler) {
|
|
// Gérer les erreurs d'authentification (401)
|
|
if (error.response?.statusCode == 401) {
|
|
// Session expirée ou invalide
|
|
_sessionId = null;
|
|
}
|
|
return handler.next(error);
|
|
}));
|
|
}
|
|
|
|
// Définir l'ID de session
|
|
void setSessionId(String? sessionId) {
|
|
_sessionId = sessionId;
|
|
}
|
|
|
|
// Vérifier la connectivité réseau
|
|
Future<bool> hasInternetConnection() async {
|
|
final connectivityResult = await (Connectivity().checkConnectivity());
|
|
return connectivityResult != ConnectivityResult.none;
|
|
}
|
|
|
|
// Méthode POST générique
|
|
Future<Response> post(String path, {dynamic data}) async {
|
|
try {
|
|
return await _dio.post(path, data: data);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Méthode GET générique
|
|
Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) async {
|
|
try {
|
|
return await _dio.get(path, queryParameters: queryParameters);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Méthode PUT générique
|
|
Future<Response> put(String path, {dynamic data}) async {
|
|
try {
|
|
return await _dio.put(path, data: data);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Méthode DELETE générique
|
|
Future<Response> delete(String path) async {
|
|
try {
|
|
return await _dio.delete(path);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Authentification avec PHP session
|
|
Future<Map<String, dynamic>> login(String username, String password, {String type = 'admin'}) async {
|
|
try {
|
|
final response = await _dio.post(AppKeys.loginEndpoint, data: {
|
|
'username': username,
|
|
'password': password,
|
|
'type': type, // Ajouter le type de connexion (user ou admin)
|
|
});
|
|
|
|
// Vérifier la structure de la réponse
|
|
final data = response.data as Map<String, dynamic>;
|
|
final status = data['status'] as String?;
|
|
|
|
// Afficher le message en cas d'erreur
|
|
if (status != 'success') {
|
|
final message = data['message'] as String?;
|
|
debugPrint('Erreur d\'authentification: $message');
|
|
}
|
|
|
|
// Si le statut est 'success', récupérer le session_id
|
|
if (status == 'success' && data.containsKey('session_id')) {
|
|
final sessionId = data['session_id'];
|
|
// Définir la session pour les futures requêtes
|
|
if (sessionId != null) {
|
|
setSessionId(sessionId);
|
|
}
|
|
}
|
|
|
|
return data;
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Déconnexion
|
|
Future<void> logout() async {
|
|
try {
|
|
if (_sessionId != null) {
|
|
await _dio.post(AppKeys.logoutEndpoint);
|
|
_sessionId = null;
|
|
}
|
|
} catch (e) {
|
|
// Même en cas d'erreur, on réinitialise la session
|
|
_sessionId = null;
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Utilisateurs
|
|
Future<List<UserModel>> getUsers() async {
|
|
try {
|
|
final response = await retry(
|
|
() => _dio.get('/users'),
|
|
retryIf: (e) => e is SocketException || e is TimeoutException,
|
|
);
|
|
|
|
return (response.data as List)
|
|
.map((json) => UserModel.fromJson(json))
|
|
.toList();
|
|
} catch (e) {
|
|
// Gérer les erreurs
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<UserModel> getUserById(int id) async {
|
|
try {
|
|
final response = await _dio.get('/users/$id');
|
|
return UserModel.fromJson(response.data);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<UserModel> createUser(UserModel user) async {
|
|
try {
|
|
final response = await _dio.post('/users', data: user.toJson());
|
|
return UserModel.fromJson(response.data);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<UserModel> updateUser(UserModel user) async {
|
|
try {
|
|
final response = await _dio.put('/users/${user.id}', data: user.toJson());
|
|
return UserModel.fromJson(response.data);
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
Future<void> deleteUser(String id) async {
|
|
try {
|
|
await _dio.delete('/users/$id');
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
|
|
// Espace réservé pour les futures méthodes de gestion des profils
|
|
|
|
// Espace réservé pour les futures méthodes de gestion des données
|
|
|
|
// Synchronisation en batch
|
|
Future<Map<String, dynamic>> syncData({
|
|
List<UserModel>? users,
|
|
}) async {
|
|
try {
|
|
final Map<String, dynamic> payload = {
|
|
if (users != null) 'users': users.map((u) => u.toJson()).toList(),
|
|
};
|
|
|
|
final response = await _dio.post('/sync', data: payload);
|
|
return response.data;
|
|
} catch (e) {
|
|
rethrow;
|
|
}
|
|
}
|
|
}
|