using System.Configuration; using System.Windows; using System.Windows.Forms.VisualStyles; using System.Windows.Input; using System.Windows.Threading; using HeBianGu.Base.WpfBase; using Hopetry.Models; using Hopetry.Provider; using SqlSugar; namespace Hopetry.Services; using System; using System.IO; using System.Net.Http; using System.Threading; using System.Threading.Tasks; using System.ComponentModel; using Minio; [SugarTable(TableName = "download_task")] public class MinioDownloadTask : INotifyPropertyChanged { private readonly MinioService _minio; /// /// /// public CancellationTokenSource _cts; /// /// /// 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 Bucket { get; set; } [SugarColumn(ColumnName = "object_key")] public string ObjectKey { get; set; } [SugarColumn(ColumnName = "total_size")] public long TotalSize { get; private set; } [SugarColumn(ColumnName = "downloaded")] public long Downloaded { get; private 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; } private String _downloadInfo; [SugarColumn(IsIgnore = true)] public String DownloadInfo { get => _downloadInfo; set { _downloadInfo = value; OnPropertyChanged(nameof(DownloadInfo)); } } private String _speed; [SugarColumn(IsIgnore = true)] public String Speed { get => _speed; set { _speed = value; OnPropertyChanged(nameof(Speed)); } } private Double _progress; [SugarColumn(IsIgnore = true)] public Double Progress { get { if (_progress == 0) { _progress = Downloaded == 0 ? 0 : (Downloaded * 100 / TotalSize); } return _progress; } set { _progress = value; OnPropertyChanged(nameof(Progress)); } } [SugarColumn(IsIgnore = true)] public ICommand PauseCommand { get; } [SugarColumn(IsIgnore = true)] public ICommand CancelCommand { get; } public MinioDownloadTask() { PauseCommand = new CustomCommand(OnPause); CancelCommand = new CustomCommand(OnCancel); } public MinioDownloadTask(MinioService minio, string bucket, string objectKey, string downDir, string fileSize) { Status = "等待中"; _minio = minio; Bucket = bucket; ObjectKey = objectKey; FileName = Path.GetFileName(objectKey); FilePath = downDir; CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); //var x = _minio.GetObjectMetadata(bucket, objectKey); //TotalSize = x.Result.Size; FileSize = fileSize; PauseCommand = new CustomCommand(OnPause); CancelCommand = new CustomCommand(OnCancel); } public void RefreshProgress() { OnPropertyChanged(nameof(Progress)); OnPropertyChanged("Progress"); } /// /// 下载 /// /// public async Task StartDownload() { _cts = new CancellationTokenSource(); try { var stat = await _minio.GetObjectMetadata(Bucket, 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"); await _minio.DownLoadObjectWithCallBack(Bucket, ObjectKey, FilePath, FileETag, (downloaded, total, speed) => { var progress = (double)downloaded / total * 100; Downloaded = downloaded; /*using (var client = SqlSugarConfig.GetSqlSugarScope()) { updateTask.Downloaded = downloaded; client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync(); }*/ Application.Current.Dispatcher.Invoke(() => { var remaining = total - downloaded; var seconds = speed > 0 ? remaining / speed : 0; Speed = (speed > 1048576 ? $"{speed / 1048576:f2}MB/s" : $"{speed:f2}KB/s") + $" 剩余时间 {TimeSpan.FromSeconds(seconds):mm\\:ss}"; Progress = progress; DownloadInfo = (downloaded > 1048576 ? $"{downloaded / 1048576:f2}MB" : $"{downloaded: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);*/ }); }); Status = "已完成"; updateTask.Status = Status; updateTask.FinishedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); using (var client = SqlSugarConfig.GetSqlSugarScope()) { await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync(); } Console.WriteLine($"文件{ObjectKey}下载完成"); } catch (OperationCanceledException) { Status = "已取消"; } catch (Exception ex) { Status = $"错误:{ex.Message}"; } finally { _pauseEvent.Dispose(); OnPropertyChanged(nameof(Status)); } } private void OnPause() { if (Status == "下载中") { _pauseEvent.Reset(); Status = "已暂停"; } else if (Status == "已暂停") { _pauseEvent.Set(); Status = "下载中"; } OnPropertyChanged(nameof(Status)); } private void OnCancel() { _cts?.Cancel(); Status = "已取消"; OnPropertyChanged(nameof(Status)); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }