starwork_flutter/lib/api/base_api_service.dart

121 lines
4.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:dio/dio.dart' as dioAlias;
import 'package:starwork_flutter/api/api_response.dart';
import 'package:starwork_flutter/common/constant/http_constant.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);
}
/// 统一请求方法
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');
}
}
}