|
|
@@ -4,7 +4,7 @@ import 'package:file_picker/file_picker.dart';
|
|
|
import 'fileUtils.dart';
|
|
|
|
|
|
|
|
|
-const _show_debug_info = true;
|
|
|
+const _show_debug_info = false;
|
|
|
|
|
|
|
|
|
|
|
|
@@ -16,12 +16,13 @@ enum UploadStatus {
|
|
|
}
|
|
|
|
|
|
/// 上传结果
|
|
|
-class UploadResult {
|
|
|
+class UploadResult<T> {
|
|
|
final UploadStatus status;
|
|
|
final String? filePath;
|
|
|
final double? progress;
|
|
|
final int? errorCode;
|
|
|
final String? errorReason;
|
|
|
+ final T? returnData;
|
|
|
|
|
|
bool get isCompleted => status == UploadStatus.completed;
|
|
|
bool get isUploading => status == UploadStatus.uploading;
|
|
|
@@ -41,6 +42,7 @@ class UploadResult {
|
|
|
this.progress,
|
|
|
this.errorCode,
|
|
|
this.errorReason,
|
|
|
+ this.returnData,
|
|
|
});
|
|
|
|
|
|
factory UploadResult.uploading(double progress) {
|
|
|
@@ -65,22 +67,32 @@ class UploadResult {
|
|
|
|
|
|
factory UploadResult.completed({
|
|
|
required String filePath,
|
|
|
+ T? returnData,
|
|
|
}) {
|
|
|
return UploadResult(
|
|
|
status: UploadStatus.completed,
|
|
|
filePath: filePath,
|
|
|
progress: 1.0,
|
|
|
+ returnData: returnData,
|
|
|
);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
-class HttpDownloader {
|
|
|
+
|
|
|
+/// -----------------------------------------------------------
|
|
|
+/// HttpUploader
|
|
|
+///
|
|
|
+
|
|
|
+class HttpUploader {
|
|
|
|
|
|
//上传
|
|
|
- static Future<UploadResult> upload({
|
|
|
+ static Future<UploadResult<T>> upload<T>({
|
|
|
required String receiverUrl,
|
|
|
String? filePath,
|
|
|
+ String? fileName,
|
|
|
+ Map<String, String>? headers,
|
|
|
+ Map<String, dynamic>? extraData,
|
|
|
void Function(UploadResult)? onProgress,
|
|
|
}) async {
|
|
|
|
|
|
@@ -90,7 +102,7 @@ class HttpDownloader {
|
|
|
if (await isFileExists(filePath)) {
|
|
|
selectedFilePath = filePath;
|
|
|
} else {
|
|
|
- final result = UploadResult.failed(
|
|
|
+ final result = UploadResult<T>.failed(
|
|
|
errorCode: UploadResult.errorCodeFileIsNotExist,
|
|
|
errorReason: 'file is not exist',
|
|
|
);
|
|
|
@@ -102,7 +114,7 @@ class HttpDownloader {
|
|
|
} else {
|
|
|
FilePickerResult? result = await FilePicker.platform.pickFiles();
|
|
|
if (result == null) {
|
|
|
- final result = UploadResult.failed(
|
|
|
+ final result = UploadResult<T>.failed(
|
|
|
errorCode: UploadResult.errorCodeUserCancel,
|
|
|
errorReason: 'Selection canceled by user',
|
|
|
);
|
|
|
@@ -116,7 +128,8 @@ class HttpDownloader {
|
|
|
}
|
|
|
|
|
|
FormData formData = FormData.fromMap({
|
|
|
- "file": await MultipartFile.fromFile(selectedFilePath),
|
|
|
+ 'file': await MultipartFile.fromFile(selectedFilePath, filename: fileName),
|
|
|
+ ...?extraData,
|
|
|
});
|
|
|
|
|
|
final dio = Dio();
|
|
|
@@ -125,26 +138,35 @@ class HttpDownloader {
|
|
|
if (_show_debug_info) {
|
|
|
print('┌────────────────────────────────────────────────────────────────────────────────────────');
|
|
|
print('│ ⬆️ start upload file: $selectedFilePath');
|
|
|
+ print('│ toServer: $receiverUrl');
|
|
|
print('└────────────────────────────────────────────────────────────────────────────────────────');
|
|
|
}
|
|
|
|
|
|
- final response = await dio.post(
|
|
|
+ final response = await dio.post<T>(
|
|
|
receiverUrl,
|
|
|
data: formData,
|
|
|
+ options: Options(
|
|
|
+ headers: headers,
|
|
|
+ contentType: 'multipart/form-data',
|
|
|
+ ),
|
|
|
onSendProgress: (sent, total) {
|
|
|
if (_show_debug_info) {
|
|
|
print('upload: $sent / $total');
|
|
|
}
|
|
|
if (onProgress != null) {
|
|
|
- onProgress(UploadResult.uploading(sent / (total * 100)));
|
|
|
+ final progress = total != 0 ? sent / total : 0.0;
|
|
|
+ onProgress(UploadResult<T>.uploading(progress));
|
|
|
}
|
|
|
},
|
|
|
);
|
|
|
|
|
|
if (_show_debug_info) {
|
|
|
- print('$filePath 上传完成: $response.data');
|
|
|
+ print('$filePath 上传完成: $response');
|
|
|
}
|
|
|
- final result = UploadResult.completed(filePath: selectedFilePath);
|
|
|
+ final result = UploadResult<T>.completed(
|
|
|
+ filePath: selectedFilePath,
|
|
|
+ returnData: response.data,
|
|
|
+ );
|
|
|
if (onProgress != null) {
|
|
|
onProgress(result);
|
|
|
}
|
|
|
@@ -152,7 +174,7 @@ class HttpDownloader {
|
|
|
|
|
|
} catch (e) {
|
|
|
print('上传失败: $e');
|
|
|
- final result = UploadResult.failed(
|
|
|
+ final result = UploadResult<T>.failed(
|
|
|
errorReason: e.toString(),
|
|
|
);
|
|
|
if (onProgress != null) {
|