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; /// /// /// public CancellationTokenSource StopDownTs; /// /// /// 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; } /// /// 0 普通对象 1 文件夹 2 存储桶 /// [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}"; } /// /// 下载 /// /// 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; var localDir = Type == 1 ? FilePath : Path.Combine(FilePath, BucketName); try { await Minio.DownLoadObject(BucketName, item.Key, localDir, item.ETag, 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(); } }