智慧水务管理系统 - 精河县供水工程综合管理平台

api_service.dart 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import 'package:dio/dio.dart';
  2. import 'package:flutter/foundation.dart';
  3. import 'auth_service.dart';
  4. /// 全局 HTTP 客户端 —— Dio 封装 + Token 拦截器
  5. class ApiService {
  6. ApiService._internal();
  7. static final ApiService instance = ApiService._internal();
  8. late final Dio dio;
  9. AuthService? _authService;
  10. /// 在 app 启动时调用一次,注入 AuthService 以便拦截器读取 token
  11. void init(AuthService auth) {
  12. _authService = auth;
  13. }
  14. /// 工厂方法:外部通过 ApiService.instance 使用
  15. factory ApiService() => instance;
  16. // --------------- Dio 初始化 ---------------
  17. Dio _createDio() {
  18. final d = Dio(BaseOptions(
  19. baseUrl: 'http://10.0.2.2:8080/api',
  20. connectTimeout: const Duration(seconds: 15),
  21. receiveTimeout: const Duration(seconds: 15),
  22. headers: {'Content-Type': 'application/json'},
  23. ));
  24. // ---------- Token 拦截器 ----------
  25. d.interceptors.add(InterceptorsWrapper(
  26. onRequest: (options, handler) {
  27. final token = _authService?.token ?? '';
  28. if (token.isNotEmpty) {
  29. options.headers['Authorization'] = 'Bearer $token';
  30. }
  31. debugPrint('→ ${options.method} ${options.uri}');
  32. handler.next(options);
  33. },
  34. onResponse: (response, handler) {
  35. debugPrint('← ${response.statusCode} ${response.requestOptions.uri}');
  36. handler.next(response);
  37. },
  38. onError: (error, handler) async {
  39. debugPrint('✗ ${error.message} ${error.requestOptions.uri}');
  40. // 401 → Token 过期,自动清除登录态
  41. if (error.response?.statusCode == 401) {
  42. await _authService?.logout();
  43. }
  44. handler.next(error);
  45. },
  46. ));
  47. // ---------- 日志拦截器(仅 debug) ----------
  48. if (kDebugMode) {
  49. d.interceptors.add(LogInterceptor(
  50. requestBody: true,
  51. responseBody: true,
  52. logPrint: (obj) => debugPrint(obj.toString()),
  53. ));
  54. }
  55. return d;
  56. }
  57. /// 懒加载 Dio 实例
  58. Dio get client {
  59. dio = _createDio();
  60. return dio;
  61. }
  62. // --------------- 便捷方法 ---------------
  63. Future<Response> get(String path, {Map<String, dynamic>? queryParameters}) {
  64. return client.get(path, queryParameters: queryParameters);
  65. }
  66. Future<Response> post(String path, {dynamic data, Map<String, dynamic>? queryParameters}) {
  67. return client.post(path, data: data, queryParameters: queryParameters);
  68. }
  69. Future<Response> put(String path, {dynamic data, Map<String, dynamic>? queryParameters}) {
  70. return client.put(path, data: data, queryParameters: queryParameters);
  71. }
  72. Future<Response> delete(String path, {dynamic data, Map<String, dynamic>? queryParameters}) {
  73. return client.delete(path, data: data, queryParameters: queryParameters);
  74. }
  75. Future<Response> patch(String path, {dynamic data, Map<String, dynamic>? queryParameters}) {
  76. return client.patch(path, data: data, queryParameters: queryParameters);
  77. }
  78. }