import 'package:dio/dio.dart'; import 'package:flutter/foundation.dart'; import 'auth_service.dart'; /// 全局 HTTP 客户端 —— Dio 封装 + Token 拦截器 class ApiService { ApiService._internal(); static final ApiService instance = ApiService._internal(); late final Dio dio; AuthService? _authService; /// 在 app 启动时调用一次,注入 AuthService 以便拦截器读取 token void init(AuthService auth) { _authService = auth; } /// 工厂方法:外部通过 ApiService.instance 使用 factory ApiService() => instance; // --------------- Dio 初始化 --------------- Dio _createDio() { final d = Dio(BaseOptions( baseUrl: 'http://10.0.2.2:8080/api', connectTimeout: const Duration(seconds: 15), receiveTimeout: const Duration(seconds: 15), headers: {'Content-Type': 'application/json'}, )); // ---------- Token 拦截器 ---------- d.interceptors.add(InterceptorsWrapper( onRequest: (options, handler) { final token = _authService?.token ?? ''; if (token.isNotEmpty) { options.headers['Authorization'] = 'Bearer $token'; } debugPrint('→ ${options.method} ${options.uri}'); handler.next(options); }, onResponse: (response, handler) { debugPrint('← ${response.statusCode} ${response.requestOptions.uri}'); handler.next(response); }, onError: (error, handler) async { debugPrint('✗ ${error.message} ${error.requestOptions.uri}'); // 401 → Token 过期,自动清除登录态 if (error.response?.statusCode == 401) { await _authService?.logout(); } handler.next(error); }, )); // ---------- 日志拦截器(仅 debug) ---------- if (kDebugMode) { d.interceptors.add(LogInterceptor( requestBody: true, responseBody: true, logPrint: (obj) => debugPrint(obj.toString()), )); } return d; } /// 懒加载 Dio 实例 Dio get client { dio = _createDio(); return dio; } // --------------- 便捷方法 --------------- Future get(String path, {Map? queryParameters}) { return client.get(path, queryParameters: queryParameters); } Future post(String path, {dynamic data, Map? queryParameters}) { return client.post(path, data: data, queryParameters: queryParameters); } Future put(String path, {dynamic data, Map? queryParameters}) { return client.put(path, data: data, queryParameters: queryParameters); } Future delete(String path, {dynamic data, Map? queryParameters}) { return client.delete(path, data: data, queryParameters: queryParameters); } Future patch(String path, {dynamic data, Map? queryParameters}) { return client.patch(path, data: data, queryParameters: queryParameters); } }