ToneSnap_FSX_Flutter/lib/data/network/dio_client.dart
fengshengxiong da21720c3c 1.首页增加下拉刷新
2.修改下载状态监听方式,实现全局同步
3.修复搜索无结果时页面报错
4.歌单页面点击播放全部和随机是播放当前歌单列表
2024-08-06 15:52:07 +08:00

183 lines
5.5 KiB
Dart

// Author: fengshengxiong
// Date: 2024/5/9
// Description: dio封装
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
import 'package:tone_snap/components/base_easyloading.dart';
import 'package:tone_snap/data/api/music_api.dart';
import 'package:tone_snap/data/network/base_error.dart';
import 'package:tone_snap/data/network/dio_interceptor.dart';
import 'package:tone_snap/utils/log_util.dart';
class DioClient {
static final DioClient _instance = DioClient._internal();
factory DioClient({String? baseUrl}) => getInstance(baseUrl: baseUrl);
late Dio _dio;
static DioClient getInstance({String? baseUrl}) {
if (baseUrl == null) {
return _instance._defaultBaseUrl();
} else {
return _instance._newBaseUrl(baseUrl);
}
}
/// 默认域名
DioClient _defaultBaseUrl() {
if (_dio.options.baseUrl != MusicApi.baseUrl) {
_dio.options.baseUrl = MusicApi.baseUrl;
}
return _instance;
}
/// 用于指定特定域名
DioClient _newBaseUrl(String baseUrl) {
_dio.options.baseUrl = baseUrl;
return _instance;
}
DioClient._internal() {
_dio = Dio();
final baseOptions = BaseOptions(
baseUrl: MusicApi.baseUrl,
connectTimeout: const Duration(seconds: 30),
receiveTimeout: const Duration(seconds: 30),
);
_dio.options = baseOptions;
_dio.interceptors.add(DioInterceptor());
_dio.interceptors.add(PrettyDioLogger(
requestHeader: false,
requestBody: true,
responseBody: false,
compact: false,
maxWidth: 160,
));
}
/// 请求
Future request<T>(
String path, {
required RequestMethod requestMethod,
dynamic data,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
Options? options,
bool isFormData = false,
T Function(Map<String, dynamic>)? formJson,
required Function(T? result) success,
Function(BaseError baseError)? fail,
bool showLoading = false,
bool showToast = false,
}) async {
try {
BaseEasyLoading.loading(show: showLoading);
_dio.options.method = requestMethod.method;
Response response = await _dio.request(
path,
data: isFormData ? FormData.fromMap(data) : data,
queryParameters: queryParameters,
cancelToken: cancelToken,
options: options,
);
BaseEasyLoading.dismiss(dismiss: showLoading);
if (response.statusCode == HttpStatus.ok) {
if (response.data != null && formJson != null) {
success(formJson(response.data));
} else {
success(response.data);
}
}
} catch (e) {
BaseError baseError = getError(e);
if (fail != null) fail(baseError);
BaseEasyLoading.toast(baseError.message, show: showToast);
LogUtil.e(e.toString());
}
}
/// 下载
Future<void> download(
String urlPath,
dynamic savePath, {
bool showToast = false,
ProgressCallback? onReceiveProgress,
Map<String, dynamic>? queryParameters,
CancelToken? cancelToken,
data,
Options? options,
required Function() success,
Function(BaseError? err)? fail,
}) async {
try {
await _dio.download(
urlPath,
savePath,
onReceiveProgress: onReceiveProgress,
queryParameters: queryParameters,
cancelToken: cancelToken,
data: data,
options: Options(receiveTimeout: const Duration(seconds: 0)),
);
success();
} catch (e) {
BaseError baseError = getError(e);
if (fail != null) fail(baseError);
BaseEasyLoading.toast(baseError.message, show: showToast);
LogUtil.e(baseError.message);
}
}
BaseError getError(Object e) {
if (e.runtimeType == DioException) {
switch ((e as DioException).type) {
case DioExceptionType.connectionTimeout:
return OtherError(statusCode: DioExceptionType.connectionTimeout.index, statusMessage: 'Connection timed out');
case DioExceptionType.sendTimeout:
return OtherError(statusCode: DioExceptionType.sendTimeout.index, statusMessage: 'Send timeout');
case DioExceptionType.receiveTimeout:
return OtherError(statusCode: DioExceptionType.receiveTimeout.index, statusMessage: 'Receive timeout');
case DioExceptionType.badCertificate:
return OtherError(statusCode: DioExceptionType.badCertificate.index, statusMessage: 'Certificate error');
case DioExceptionType.cancel:
return OtherError(statusCode: DioExceptionType.cancel.index, statusMessage: 'Request canceled');
case DioExceptionType.connectionError:
return OtherError(statusCode: DioExceptionType.connectionError.index, statusMessage: 'Connection error');
case DioExceptionType.unknown:
return OtherError(statusCode: DioExceptionType.unknown.index, statusMessage: 'Unknown error');
case DioExceptionType.badResponse:
final response = e.response;
if (response!.statusCode == 401) {
return NeedLogin();
} else if (response.statusCode == 403) {
return NeedAuth();
} else {
return OtherError(
statusCode: response.statusCode,
statusMessage: response.statusMessage,
);
}
}
}
return OtherError(statusCode: -1, statusMessage: 'Unknown error');
}
}
enum RequestMethod {
get('GET'),
post('POST'),
put('PUT'),
head('HEAD'),
delete('DELETE'),
patch('PATCH');
const RequestMethod(
this.method,
);
final String method;
}