httpUploader.dart 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import 'package:dio/dio.dart';
  2. import 'package:file_picker/file_picker.dart';
  3. import 'fileUtils.dart';
  4. const _show_debug_info = true;
  5. /// 上传状态枚举
  6. enum UploadStatus {
  7. uploading,
  8. completed,
  9. failed,
  10. }
  11. /// 上传结果
  12. class UploadResult {
  13. final UploadStatus status;
  14. final String? filePath;
  15. final double? progress;
  16. final int? errorCode;
  17. final String? errorReason;
  18. bool get isCompleted => status == UploadStatus.completed;
  19. bool get isUploading => status == UploadStatus.uploading;
  20. bool get isFailed => status == UploadStatus.failed;
  21. /// ----- error code -----
  22. static const int errorCodeError = -1;
  23. static const int errorCodeUserCancel = 1;
  24. static const int errorCodeFileIsNotExist = -2;
  25. /// ----- constructor -----
  26. UploadResult({
  27. required this.status,
  28. this.filePath,
  29. this.progress,
  30. this.errorCode,
  31. this.errorReason,
  32. });
  33. factory UploadResult.uploading(double progress) {
  34. if (progress < 0) { progress = 0; }
  35. else if (progress > 1) { progress = 1; }
  36. return UploadResult(
  37. status: UploadStatus.uploading,
  38. progress: progress,
  39. );
  40. }
  41. factory UploadResult.failed({
  42. int errorCode = errorCodeError,
  43. String? errorReason,
  44. }) {
  45. return UploadResult(
  46. status: UploadStatus.failed,
  47. errorCode: errorCode,
  48. errorReason: errorReason,
  49. );
  50. }
  51. factory UploadResult.completed({
  52. required String filePath,
  53. }) {
  54. return UploadResult(
  55. status: UploadStatus.completed,
  56. filePath: filePath,
  57. progress: 1.0,
  58. );
  59. }
  60. }
  61. class HttpDownloader {
  62. //上传
  63. static Future<UploadResult> upload({
  64. required String receiverUrl,
  65. String? filePath,
  66. void Function(UploadResult)? onProgress,
  67. }) async {
  68. // 选择文件
  69. String selectedFilePath;
  70. if (filePath != null) {
  71. if (await isFileExists(filePath)) {
  72. selectedFilePath = filePath;
  73. } else {
  74. final result = UploadResult.failed(
  75. errorCode: UploadResult.errorCodeFileIsNotExist,
  76. errorReason: 'file is not exist',
  77. );
  78. if (onProgress != null) {
  79. onProgress(result);
  80. }
  81. return result;
  82. }
  83. } else {
  84. FilePickerResult? result = await FilePicker.platform.pickFiles();
  85. if (result == null) {
  86. final result = UploadResult.failed(
  87. errorCode: UploadResult.errorCodeUserCancel,
  88. errorReason: 'Selection canceled by user',
  89. );
  90. if (onProgress != null) {
  91. onProgress(result);
  92. }
  93. return result;
  94. }
  95. PlatformFile file = result.files.first;
  96. selectedFilePath = file.path!;
  97. }
  98. FormData formData = FormData.fromMap({
  99. "file": await MultipartFile.fromFile(selectedFilePath),
  100. });
  101. final dio = Dio();
  102. try {
  103. if (_show_debug_info) {
  104. print('┌────────────────────────────────────────────────────────────────────────────────────────');
  105. print('│ ⬆️ start upload file: $selectedFilePath');
  106. print('└────────────────────────────────────────────────────────────────────────────────────────');
  107. }
  108. final response = await dio.post(
  109. receiverUrl,
  110. data: formData,
  111. onSendProgress: (sent, total) {
  112. if (_show_debug_info) {
  113. print('upload: $sent / $total');
  114. }
  115. if (onProgress != null) {
  116. onProgress(UploadResult.uploading(sent / (total * 100)));
  117. }
  118. },
  119. );
  120. if (_show_debug_info) {
  121. print('$filePath 上传完成: $response.data');
  122. }
  123. final result = UploadResult.completed(filePath: selectedFilePath);
  124. if (onProgress != null) {
  125. onProgress(result);
  126. }
  127. return result;
  128. } catch (e) {
  129. print('上传失败: $e');
  130. final result = UploadResult.failed(
  131. errorReason: e.toString(),
  132. );
  133. if (onProgress != null) {
  134. onProgress(result);
  135. }
  136. return result;
  137. }
  138. }
  139. }