feat(mobile-next): 导入官方 openim-flutter-demo 固定基线 3.8.3-patch.3 并完成双构建
- 上游: github.com/OpenIMSDK/openim-flutter-demo tag 3.8.3-patch.3 commit b3dfdb1e8aaeaaf6f0793e10cadd20d5c184a31f - 并行目录 mobile-next/ 原样导入(含 LICENSE),不覆盖现网 mobile/ - 锁定 Flutter 3.24.5 / Dart 3.5.4 / JDK 17 / Gradle 7.6.3 / AGP 7.3.1 - 实测 Android debug 与 release 构建均成功(见 docs/mobile-next-baseline-import.md) - 本提交可单独回退:git revert 1db1229(重写前) Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -0,0 +1,161 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:openim_common/openim_common.dart';
|
||||
import 'package:talker_dio_logger/talker_dio_logger.dart';
|
||||
|
||||
class ApiService {
|
||||
static final _instance = ApiService._internal();
|
||||
|
||||
factory ApiService() {
|
||||
return _instance;
|
||||
}
|
||||
|
||||
final Dio dio = Dio();
|
||||
|
||||
ApiService._internal() {
|
||||
final talkerDioLogger = TalkerDioLogger(
|
||||
settings: const TalkerDioLoggerSettings(
|
||||
printRequestHeaders: kDebugMode,
|
||||
printRequestData: kDebugMode,
|
||||
printResponseMessage: kDebugMode,
|
||||
printResponseData: kDebugMode,
|
||||
printResponseHeaders: false,
|
||||
),
|
||||
);
|
||||
|
||||
dio.options
|
||||
..connectTimeout = const Duration(seconds: 30)
|
||||
..receiveTimeout = const Duration(seconds: 30);
|
||||
|
||||
dio.interceptors
|
||||
..add(talkerDioLogger)
|
||||
..add(
|
||||
InterceptorsWrapper(
|
||||
onRequest: (options, handler) {
|
||||
return handler.next(options); //continue
|
||||
},
|
||||
onResponse: (response, handler) {
|
||||
return handler.next(response); // continue
|
||||
},
|
||||
onError: (DioException e, handler) {
|
||||
return handler.next(e); //continue
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
dio.options.connectTimeout = const Duration(seconds: 30);
|
||||
dio.options.receiveTimeout = const Duration(seconds: 30);
|
||||
}
|
||||
|
||||
void setBaseUrl(String baseUrl) {
|
||||
dio.options.baseUrl = baseUrl;
|
||||
}
|
||||
|
||||
void setToken(String token) {
|
||||
dio.options.headers['token'] = token;
|
||||
}
|
||||
|
||||
Future get(String path, {Map<String, dynamic>? queryParams}) async {
|
||||
try {
|
||||
dio.options.headers['operationID'] = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
|
||||
final response = await dio.get(path, queryParameters: queryParams);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final result = ApiResponse.fromJson(response.data as Map<String, dynamic>);
|
||||
|
||||
if (result.errCode == 0) {
|
||||
return result.data;
|
||||
} else {
|
||||
return Future.error(result.errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
return Future.error(response.data);
|
||||
} on DioException catch (e) {
|
||||
_handleError(e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future post(String path, {Map<String, dynamic>? data, String? token}) async {
|
||||
try {
|
||||
final operationID = DateTime.now().millisecondsSinceEpoch.toString();
|
||||
dio.options.headers['operationID'] = operationID;
|
||||
|
||||
final response = await dio.post(path, data: data);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final result = ApiResponse.fromJson(response.data as Map<String, dynamic>);
|
||||
|
||||
if (result.errCode == 0) {
|
||||
return result.data;
|
||||
} else {
|
||||
final exception = ApiException(code: result.errCode, message: result.errMsg, operationID: operationID);
|
||||
|
||||
return Future.error(exception);
|
||||
}
|
||||
}
|
||||
|
||||
return Future.error(response.data);
|
||||
} on DioException catch (e) {
|
||||
_handleError(e);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future download(
|
||||
String url, {
|
||||
required String cachePath,
|
||||
CancelToken? cancelToken,
|
||||
Function(int count, int total)? onProgress,
|
||||
}) {
|
||||
return dio.download(
|
||||
url,
|
||||
cachePath,
|
||||
cancelToken: cancelToken,
|
||||
onReceiveProgress: onProgress,
|
||||
);
|
||||
}
|
||||
|
||||
void _handleError(DioException error) {
|
||||
Logger.print('DioError: ${error.message}', isError: true);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiResponse {
|
||||
int errCode;
|
||||
String errMsg;
|
||||
String errDlt;
|
||||
dynamic data;
|
||||
|
||||
ApiResponse.fromJson(Map<String, dynamic> map)
|
||||
: errCode = map["errCode"] ?? -1,
|
||||
errMsg = map["errMsg"] ?? '',
|
||||
errDlt = map["errDlt"] ?? '',
|
||||
data = map["data"];
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final data = <String, dynamic>{};
|
||||
data['errCode'] = errCode;
|
||||
data['errMsg'] = errMsg;
|
||||
data['errDlt'] = errDlt;
|
||||
data['data'] = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return jsonEncode(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ApiException implements Exception {
|
||||
final int code;
|
||||
final String? message;
|
||||
final String? operationID;
|
||||
|
||||
ApiException({required this.code, this.message, this.operationID});
|
||||
}
|
||||
Reference in New Issue
Block a user