146 lines
5.1 KiB
Dart
146 lines
5.1 KiB
Dart
import 'package:dio/dio.dart' as dioAlias;
|
||
import 'package:dio/dio.dart';
|
||
|
||
import 'package:starwork_flutter/api/api_response.dart';
|
||
import 'package:starwork_flutter/base/app_logger.dart';
|
||
import 'package:starwork_flutter/common/constant/cache_keys.dart';
|
||
import 'package:starwork_flutter/common/constant/http_constant.dart';
|
||
import 'package:starwork_flutter/common/utils/shared_preferences_utils.dart';
|
||
import 'package:starwork_flutter/flavors.dart';
|
||
import 'package:flutter/foundation.dart'; // 用于 debugPrint
|
||
|
||
class BaseApiService {
|
||
final dioAlias.Dio dio = dioAlias.Dio();
|
||
|
||
BaseApiService() {
|
||
dio.options.baseUrl = F.apiHost;
|
||
dio.options.connectTimeout = const Duration(seconds: 30);
|
||
dio.options.receiveTimeout = const Duration(seconds: 30);
|
||
// 添加拦截器
|
||
dio.interceptors.add(InterceptorsWrapper(
|
||
onRequest: (options, handler) {
|
||
var token = SharedPreferencesUtils.getString(CacheKeys.token);
|
||
AppLogger.info('token:${token}');
|
||
if (token != null) {
|
||
options.headers['Authorization'] = 'Bearer $token';
|
||
}
|
||
|
||
/// 请求拦截器
|
||
return handler.next(options);
|
||
},
|
||
onResponse: (response, handler) {
|
||
/// 响应拦截器
|
||
return handler.next(response);
|
||
},
|
||
onError: (DioError e, handler) {
|
||
// 异常拦截器
|
||
return handler.next(e);
|
||
},
|
||
));
|
||
}
|
||
|
||
/// 统一请求方法
|
||
Future<ApiResponse<T>> makeRequest<T>({
|
||
required String path,
|
||
String method = HttpConstant.post,
|
||
dynamic data,
|
||
Map<String, dynamic>? queryParameters,
|
||
required T Function(dynamic) fromJson,
|
||
}) async {
|
||
try {
|
||
// 🔍 打印请求信息(更详细控制)
|
||
if (kDebugMode) {
|
||
final uri = Uri.parse('${dio.options.baseUrl}$path');
|
||
final queryString = queryParameters != null ? '?${uri.queryParameters.toString()}' : '';
|
||
debugPrint('🟦 API Request: $method ${uri.toString()}$queryString');
|
||
if (data != null) {
|
||
debugPrint('🟦 Request Body: $data');
|
||
}
|
||
}
|
||
|
||
dioAlias.Response response;
|
||
|
||
switch (method.toUpperCase()) {
|
||
case HttpConstant.get:
|
||
response = await dio.get(path, queryParameters: queryParameters);
|
||
break;
|
||
case HttpConstant.post:
|
||
response = await dio.post(path, data: data, queryParameters: queryParameters);
|
||
break;
|
||
case HttpConstant.put:
|
||
response = await dio.put(path, data: data, queryParameters: queryParameters);
|
||
break;
|
||
case HttpConstant.delete:
|
||
response = await dio.delete(path, data: data, queryParameters: queryParameters);
|
||
break;
|
||
case HttpConstant.patch:
|
||
response = await dio.patch(path, data: data, queryParameters: queryParameters);
|
||
break;
|
||
default:
|
||
return ApiResponse.error('Unsupported method: $method');
|
||
}
|
||
|
||
// ✅ 打印响应
|
||
if (kDebugMode) {
|
||
debugPrint('🟩 API Response [${response.statusCode}] ${response.requestOptions.path}');
|
||
debugPrint('🟩 Response Data: ${response.data}');
|
||
}
|
||
|
||
if (response.statusCode! >= 200 && response.statusCode! < 300) {
|
||
final jsonMap = response.data as Map<String, dynamic>;
|
||
|
||
// ✅ 直接用 ApiResponse.fromJson 解析整个响应
|
||
final apiResponse = ApiResponse<T>.fromJson(jsonMap, fromJson);
|
||
|
||
// ✅ 判断业务是否成功(根据 errorCode)
|
||
if (apiResponse.errorCode == 0) {
|
||
return apiResponse; // 直接返回,data 已解析
|
||
} else {
|
||
// 业务失败,但 data 可能有部分信息
|
||
return ApiResponse.error(
|
||
apiResponse.errorMsg ?? 'Request failed',
|
||
errorCode: apiResponse.errorCode,
|
||
data: apiResponse.data,
|
||
);
|
||
}
|
||
} else {
|
||
return ApiResponse.error(
|
||
response.statusMessage ?? 'Request failed',
|
||
errorCode: response.statusCode,
|
||
);
|
||
}
|
||
} on dioAlias.DioException catch (e) {
|
||
// ❌ 打印错误
|
||
if (kDebugMode) {
|
||
debugPrint('🟥 API Error: ${e.type} - ${e.message}');
|
||
if (e.response != null) {
|
||
debugPrint('🟥 Error Response: ${e.response?.data}');
|
||
debugPrint('🟥 Status Code: ${e.response?.statusCode}');
|
||
}
|
||
}
|
||
|
||
String message = 'Unknown error';
|
||
int? statusCode = e.response?.statusCode;
|
||
|
||
if (e.type == dioAlias.DioExceptionType.connectionTimeout) {
|
||
message = 'Connection timeout';
|
||
} else if (e.type == dioAlias.DioExceptionType.receiveTimeout) {
|
||
message = 'Server timeout';
|
||
} else if (e.type == dioAlias.DioExceptionType.badResponse) {
|
||
message = e.response?.statusMessage ?? 'Bad response';
|
||
} else if (e.type == dioAlias.DioExceptionType.connectionError) {
|
||
message = 'Network not available';
|
||
} else {
|
||
message = e.message ?? 'Something went wrong';
|
||
}
|
||
|
||
return ApiResponse.error(message, errorCode: statusCode);
|
||
} catch (e) {
|
||
if (kDebugMode) {
|
||
debugPrint('🟥 Unexpected Error: $e');
|
||
}
|
||
return ApiResponse.error('Unexpected error: $e');
|
||
}
|
||
}
|
||
}
|