FieldWorkClient/Services/MinioDownloadTask.cs

303 lines
9.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System.IO;
using System.Windows;
using HeBianGu.Base.WpfBase;
using Hopetry.Provider;
using SqlSugar;
namespace Hopetry.Services;
[SugarTable(TableName = "download_task")]
public class MinioDownloadTask : NotifyPropertyChangedBase
{
// 同步锁
private static readonly object SyncLock = new();
public MinioService Minio;
/// <summary>
///
/// </summary>
public CancellationTokenSource StopDownTs;
/// <summary>
///
/// </summary>
private ManualResetEventSlim _pauseEvent = new(true);
// 任务属性绑定到UI
[SugarColumn(ColumnName = "task_id", IsPrimaryKey = true, IsIdentity = true)]
public int TaskId { get; set; }
[SugarColumn(ColumnName = "file_name")]
public string FileName { get; set; }
[SugarColumn(ColumnName = "bucket_name")]
public string BucketName { get; set; }
[SugarColumn(ColumnName = "object_key")]
public string ObjectKey { get; set; }
[SugarColumn(ColumnName = "total_size")]
public long TotalSize { get; set; }
[SugarColumn(ColumnName = "downloaded")]
public long Downloaded { get; set; }
[SugarColumn(ColumnName = "file_path")]
public string FilePath { get; set; }
[SugarColumn(ColumnName = "status")] public string Status { get; set; }
[SugarColumn(ColumnName = "create_time")]
public string CreateTime { get; set; }
[SugarColumn(ColumnName = "finished_time")]
public string FinishedTime { get; set; }
[SugarColumn(ColumnName = "file_size")]
public string FileSize { get; set; }
[SugarColumn(ColumnName = "file_etag")]
public string FileETag { get; set; }
/// <summary>
/// 0 普通对象 1 文件夹 2 存储桶
/// </summary>
[SugarColumn(ColumnName = "type")]
public int Type { get; set; }
[SugarColumn(ColumnName = "file_number")]
public int FileNumber { get; set; }
[SugarColumn(ColumnName = "download_number")]
public int DownloadNumber { get; set; }
[SugarColumn(ColumnName = "file_icon")]
public string FileIcon { get; set; }
private string _downloadInfo;
[SugarColumn(IsIgnore = true)]
public string DownloadInfo
{
get => _downloadInfo;
set
{
_downloadInfo = value;
RaisePropertyChanged();
}
}
private String _speed;
[SugarColumn(IsIgnore = true)]
public String Speed
{
get => _speed;
set
{
_speed = value;
RaisePropertyChanged();
}
}
private Double _progress;
[SugarColumn(IsIgnore = true)]
public Double Progress
{
get
{
if (_progress == 0)
{
if (TotalSize == 0)
{
return 0d;
}
_progress = Downloaded == 0 ? 0 : (Downloaded * 100 / TotalSize);
}
return _progress;
}
set
{
_progress = value;
RaisePropertyChanged();
}
}
private string _startOrPauseIcon;
[SugarColumn(IsIgnore = true)]
public string StartOrPauseIcon
{
get => _startOrPauseIcon;
set
{
_startOrPauseIcon = value;
RaisePropertyChanged();
}
}
public MinioDownloadTask()
{
StartOrPauseIcon = "\xe76e";
Status = "等待中";
}
public MinioDownloadTask(MinioService minio, string bucketName, string objectKey, string downDir, string fileSize)
{
var suffix = objectKey[objectKey.LastIndexOf('.')..].ToLower();
FileIcon = suffix switch
{
".png" or ".jpg" or ".jpeg" or ".gif" => "\xe747",
".pdf" => "\xe804",
".doc" or ".docx" => "\xe744",
".xls" or ".xlsx" => "\xe80a",
".zip" or ".rar" or ".7z" => "\xe810",
".mp3" or ".wav" => "\xe7ff",
".mp4" or ".avi" or ".mov" => "\xe803",
".txt" => "\xe666",
_ => "\xe741" // 默认图标
};
StartOrPauseIcon = "\xe76e";
Status = "等待中";
Minio = minio;
BucketName = bucketName;
ObjectKey = objectKey;
FileName = Path.GetFileName(objectKey);
FilePath = downDir;
CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
var x = minio.GetObjectMetadata(bucketName, objectKey);
TotalSize = x.Result.Size;
FileSize = fileSize;
Speed = Status;
DownloadInfo = $"0MB/{FileSize}";
}
/// <summary>
/// 下载
/// </summary>
/// <param name="savePath"></param>
public async Task StartDownload()
{
StopDownTs = new CancellationTokenSource();
try
{
var stat = await Minio.GetObjectMetadata(BucketName, ObjectKey);
// 获取对象信息
TotalSize = stat.Size;
FileETag = stat.ETag;
Status = "下载中";
var updateTask = new MinioDownloadTask
{
TaskId = TaskId,
Status = Status,
TotalSize = TotalSize,
FileETag = FileETag
};
using (var client = SqlSugarConfig.GetSqlSugarScope())
{
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
}
Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey} 文件下载中...");
updateTask.Status = "下载中";
var humanFileSize = (TotalSize > 1048576
? $"{TotalSize / 1048576}MB"
: $"{TotalSize / 1024}KB");
var offset = Downloaded;
//Console.WriteLine("偏移量:" + (offset > 1048576 ? $"{offset / 1048576:f2}MB" : $"{(offset) / 1024:f2}KB"));
await Minio.DownLoadObjectWithCallBack(this, BucketName, ObjectKey, FilePath, FileETag,
(downloaded, total, speed) =>
{
var progress = (double)(downloaded + offset) / total * 100;
Downloaded = downloaded + offset;
Application.Current.Dispatcher.Invoke(() =>
{
var remaining = total - downloaded;
var seconds = speed > 0 ? remaining / speed : 0;
Speed = (speed > 1048576
? $"{speed / 1048576:f2}MB/s"
: $"{speed / 1024:f2}KB/s") + $" 剩余时间 {TimeSpan.FromSeconds(seconds):mm\\:ss}";
Progress = progress;
DownloadInfo = (downloaded + offset > 1048576
? $"{(downloaded + offset) / 1048576:f2}MB"
: $"{(downloaded + offset) / 1024:f2}KB") + "/" + humanFileSize;
//Console.WriteLine($"{DownloadInfo}");
/*var x =
$"{(double)downloaded / total:P1} | {speed:0.0} KB/s | 剩余 {TimeSpan.FromSeconds(seconds):mm\\:ss}";
Console.WriteLine(x);*/
});
}, offset: offset);
Status = "已完成";
var date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
FinishedTime = date;
updateTask.Status = Status;
updateTask.Downloaded = TotalSize;
updateTask.FinishedTime = date;
using (var client = SqlSugarConfig.GetSqlSugarScope())
{
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
}
Console.WriteLine($"文件{ObjectKey}下载完成");
}
finally
{
_pauseEvent.Dispose();
RaisePropertyChanged(nameof(Status));
}
}
public async Task StartDownloadDir()
{
StopDownTs = new CancellationTokenSource();
// 改变任务状态
Status = "下载中";
var updateTask = new MinioDownloadTask
{
TaskId = TaskId
};
var prefix = BucketName.Equals(ObjectKey) ? "" : ObjectKey;
var allObject = await Minio.ListAllObject(BucketName, prefix, true, StopDownTs.Token);
await foreach (var item in allObject)
{
// 验证文件是否存在
if (File.Exists(Path.Combine(FilePath, item.Key))) continue;
// 1 文件夹 2 存储桶
var localDir = Type == 1 ? FilePath : Path.Combine(FilePath, BucketName);
try
{
// 修改
await Minio.DownLoadObject(BucketName, item.Key, localDir, item.ETag,FileName, StopDownTs.Token);
}
catch (Exception e)
{
Console.WriteLine("停止运行了");
throw;
}
DownloadNumber++;
DownloadInfo = $"{DownloadNumber}/{FileNumber}";
Speed = $"已下载 {DownloadNumber}";
Progress = (double)DownloadNumber / FileNumber * 100;
using var xxx = SqlSugarConfig.GetSqlSugarScope();
updateTask.DownloadNumber = DownloadNumber;
await xxx.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
}
Status = "已完成";
var date = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
FinishedTime = date;
updateTask.Status = Status;
updateTask.FinishedTime = date;
updateTask.DownloadNumber = DownloadNumber;
using var client = SqlSugarConfig.GetSqlSugarScope();
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
}
}