fix(upload_image): 修改媒体上传文件

This commit is contained in:
2026-05-29 18:26:16 +08:00
parent 037f14b52f
commit a1b98e987e
3 changed files with 77 additions and 5 deletions
+68 -3
View File
@@ -12,7 +12,8 @@ class VideoBatchUploadQueue {
VideoBatchUploadQueue({ VideoBatchUploadQueue({
required this.contextProvider, required this.contextProvider,
required this.uploadTask, required this.uploadTask,
required this.saveTask, this.saveTask,
this.batchSaveTask,
required this.onChanged, required this.onChanged,
this.assetType = VideoBatchUploadAssetType.video, this.assetType = VideoBatchUploadAssetType.video,
this.onCompleted, this.onCompleted,
@@ -22,7 +23,8 @@ class VideoBatchUploadQueue {
final BuildContext? Function() contextProvider; final BuildContext? Function() contextProvider;
final VideoBatchUploadUploadTask uploadTask; final VideoBatchUploadUploadTask uploadTask;
final VideoBatchUploadSaveTask saveTask; final VideoBatchUploadSaveTask? saveTask;
final VideoBatchUploadBatchSaveTask? batchSaveTask;
final VoidCallback onChanged; final VoidCallback onChanged;
final VideoBatchUploadAssetType assetType; final VideoBatchUploadAssetType assetType;
final FutureOr<void> Function()? onCompleted; final FutureOr<void> Function()? onCompleted;
@@ -58,6 +60,8 @@ class VideoBatchUploadQueue {
int get finishedCount => int get finishedCount =>
_completedRemovedCount + completedCount + failedCount; _completedRemovedCount + completedCount + failedCount;
bool get _usesBatchSave => batchSaveTask != null;
Future<void> pickAndStart() async { Future<void> pickAndStart() async {
if (hasActiveUploads) { if (hasActiveUploads) {
isExpanded = true; isExpanded = true;
@@ -195,6 +199,7 @@ class VideoBatchUploadQueue {
); );
await Future.wait(workers); await Future.wait(workers);
_isRunning = false; _isRunning = false;
await _saveUploadedBatchIfNeeded();
await _notifyCompletedIfNeeded(); await _notifyCompletedIfNeeded();
} }
@@ -251,9 +256,13 @@ class VideoBatchUploadQueue {
..status = VideoBatchUploadStatus.uploaded; ..status = VideoBatchUploadStatus.uploaded;
_notifyChanged(); _notifyChanged();
if (_usesBatchSave) {
return;
}
task.status = VideoBatchUploadStatus.saving; task.status = VideoBatchUploadStatus.saving;
_notifyChanged(); _notifyChanged();
final bool saved = await saveTask(task); final bool saved = await saveTask!(task);
if (!tasks.contains(task)) { if (!tasks.contains(task)) {
return; return;
} }
@@ -290,6 +299,62 @@ class VideoBatchUploadQueue {
} }
} }
Future<void> _saveUploadedBatchIfNeeded() async {
if (!_usesBatchSave || _isDisposed) {
return;
}
final List<VideoBatchUploadTask> successfulUploadTasks = tasks
.where((VideoBatchUploadTask task) =>
task.status == VideoBatchUploadStatus.uploaded)
.toList();
if (successfulUploadTasks.isEmpty) {
return;
}
for (final VideoBatchUploadTask task in successfulUploadTasks) {
task.status = VideoBatchUploadStatus.saving;
}
_notifyChanged();
try {
final bool saved = await batchSaveTask!(List<VideoBatchUploadTask>.of(
successfulUploadTasks,
growable: false,
));
if (_isDisposed) {
return;
}
if (saved) {
_completedRemovedCount += successfulUploadTasks.length;
tasks.removeWhere(successfulUploadTasks.contains);
if (tasks.isEmpty) {
isExpanded = false;
}
return;
}
for (final VideoBatchUploadTask task in successfulUploadTasks) {
if (tasks.contains(task)) {
task
..status = VideoBatchUploadStatus.failed
..errorMessage = '入库失败';
}
}
} catch (_) {
if (_isDisposed) {
return;
}
for (final VideoBatchUploadTask task in successfulUploadTasks) {
if (tasks.contains(task)) {
task
..status = VideoBatchUploadStatus.failed
..errorMessage = '入库失败';
}
}
} finally {
_notifyChanged();
}
}
String _networkErrorText(DioException error) { String _networkErrorText(DioException error) {
switch (error.type) { switch (error.type) {
case DioExceptionType.connectionTimeout: case DioExceptionType.connectionTimeout:
@@ -14,6 +14,10 @@ typedef VideoBatchUploadSaveTask = Future<bool> Function(
VideoBatchUploadTask task, VideoBatchUploadTask task,
); );
typedef VideoBatchUploadBatchSaveTask = Future<bool> Function(
List<VideoBatchUploadTask> tasks,
);
enum VideoBatchUploadAssetType { enum VideoBatchUploadAssetType {
image, image,
video, video,
+5 -2
View File
@@ -13,18 +13,21 @@ class VideoBatchUploader {
VideoBatchUploader({ VideoBatchUploader({
required BuildContext? Function() contextProvider, required BuildContext? Function() contextProvider,
required VideoBatchUploadUploadTask uploadTask, required VideoBatchUploadUploadTask uploadTask,
required VideoBatchUploadSaveTask saveTask, VideoBatchUploadSaveTask? saveTask,
VideoBatchUploadBatchSaveTask? batchSaveTask,
VideoBatchUploadAssetType assetType = VideoBatchUploadAssetType.video, VideoBatchUploadAssetType assetType = VideoBatchUploadAssetType.video,
VoidCallback? onChanged, VoidCallback? onChanged,
VideoBatchUploadCallback? onCompleted, VideoBatchUploadCallback? onCompleted,
int? maxAssets, int? maxAssets,
int? maxConcurrent, int? maxConcurrent,
}) : _contextProvider = contextProvider, }) : assert(saveTask != null || batchSaveTask != null),
_contextProvider = contextProvider,
_onChanged = onChanged { _onChanged = onChanged {
queue = VideoBatchUploadQueue( queue = VideoBatchUploadQueue(
contextProvider: contextProvider, contextProvider: contextProvider,
uploadTask: uploadTask, uploadTask: uploadTask,
saveTask: saveTask, saveTask: saveTask,
batchSaveTask: batchSaveTask,
onChanged: _handleChanged, onChanged: _handleChanged,
assetType: assetType, assetType: assetType,
onCompleted: onCompleted, onCompleted: onCompleted,