2025-04-12 13:23:12 +08:00
|
|
|
|
using System.Configuration;
|
|
|
|
|
|
using System.Windows;
|
2025-04-15 10:29:41 +08:00
|
|
|
|
using System.Windows.Forms.VisualStyles;
|
2025-04-10 13:17:39 +08:00
|
|
|
|
using System.Windows.Input;
|
2025-04-15 14:05:06 +08:00
|
|
|
|
using System.Windows.Threading;
|
2025-04-10 13:17:39 +08:00
|
|
|
|
using HeBianGu.Base.WpfBase;
|
|
|
|
|
|
using Hopetry.Models;
|
2025-04-12 13:23:12 +08:00
|
|
|
|
using Hopetry.Provider;
|
2025-04-10 13:17:39 +08:00
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
2025-04-15 14:05:06 +08:00
|
|
|
|
public CancellationTokenSource _cts;
|
2025-04-10 13:17:39 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private ManualResetEventSlim _pauseEvent = new(true);
|
|
|
|
|
|
|
|
|
|
|
|
// 任务属性(绑定到UI)
|
2025-04-12 13:23:12 +08:00
|
|
|
|
[SugarColumn(ColumnName = "task_id", IsPrimaryKey = true, IsIdentity = true)]
|
|
|
|
|
|
public int TaskId { get; set; }
|
2025-04-10 13:17:39 +08:00
|
|
|
|
|
|
|
|
|
|
[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; }
|
|
|
|
|
|
|
2025-04-12 16:43:28 +08:00
|
|
|
|
[SugarColumn(ColumnName = "status")] public string Status { get; set; } = "等待中";
|
2025-04-10 13:17:39 +08:00
|
|
|
|
|
2025-04-14 15:56:38 +08:00
|
|
|
|
[SugarColumn(ColumnName = "create_time")]
|
|
|
|
|
|
public string CreateTime { get; set; }
|
2025-04-14 17:05:48 +08:00
|
|
|
|
|
2025-04-14 15:56:38 +08:00
|
|
|
|
[SugarColumn(ColumnName = "finished_time")]
|
|
|
|
|
|
public string FinishedTime { get; set; }
|
2025-04-15 09:40:29 +08:00
|
|
|
|
|
2025-04-14 17:05:48 +08:00
|
|
|
|
[SugarColumn(ColumnName = "file_size")]
|
|
|
|
|
|
public string FileSize { get; set; }
|
|
|
|
|
|
|
2025-04-15 09:40:29 +08:00
|
|
|
|
[SugarColumn(ColumnName = "file_etag")]
|
|
|
|
|
|
public string FileETag { get; set; }
|
2025-04-15 10:29:41 +08:00
|
|
|
|
|
2025-04-15 14:05:06 +08:00
|
|
|
|
private Double _progress;
|
2025-04-15 10:29:41 +08:00
|
|
|
|
|
2025-04-12 13:23:12 +08:00
|
|
|
|
[SugarColumn(IsIgnore = true)]
|
2025-04-15 14:05:06 +08:00
|
|
|
|
public Double Progress
|
2025-04-10 13:17:39 +08:00
|
|
|
|
{
|
2025-04-15 10:29:41 +08:00
|
|
|
|
get
|
|
|
|
|
|
{
|
2025-04-15 14:05:06 +08:00
|
|
|
|
if (_progress == 0)
|
2025-04-15 10:29:41 +08:00
|
|
|
|
{
|
2025-04-15 14:05:06 +08:00
|
|
|
|
_progress = Downloaded == 0 ? 0 : (Downloaded * 100 / TotalSize);
|
2025-04-15 10:29:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return _progress;
|
|
|
|
|
|
}
|
|
|
|
|
|
set
|
|
|
|
|
|
{
|
|
|
|
|
|
_progress = value;
|
|
|
|
|
|
OnPropertyChanged(nameof(Progress));
|
|
|
|
|
|
}
|
2025-04-10 13:17:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-12 13:23:12 +08:00
|
|
|
|
[SugarColumn(IsIgnore = true)] public ICommand PauseCommand { get; }
|
|
|
|
|
|
[SugarColumn(IsIgnore = true)] public ICommand CancelCommand { get; }
|
2025-04-10 13:17:39 +08:00
|
|
|
|
|
|
|
|
|
|
public MinioDownloadTask()
|
|
|
|
|
|
{
|
|
|
|
|
|
PauseCommand = new CustomCommand(OnPause);
|
|
|
|
|
|
CancelCommand = new CustomCommand(OnCancel);
|
|
|
|
|
|
}
|
2025-04-12 13:23:12 +08:00
|
|
|
|
|
2025-04-15 09:40:29 +08:00
|
|
|
|
public MinioDownloadTask(MinioService minio, string bucket, string objectKey, string downDir, string fileSize)
|
2025-04-10 13:17:39 +08:00
|
|
|
|
{
|
2025-04-12 15:50:38 +08:00
|
|
|
|
Status = "等待中";
|
2025-04-10 13:17:39 +08:00
|
|
|
|
_minio = minio;
|
|
|
|
|
|
Bucket = bucket;
|
|
|
|
|
|
ObjectKey = objectKey;
|
|
|
|
|
|
FileName = Path.GetFileName(objectKey);
|
2025-04-12 16:24:15 +08:00
|
|
|
|
FilePath = downDir;
|
2025-04-14 15:56:38 +08:00
|
|
|
|
CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
2025-04-14 17:05:48 +08:00
|
|
|
|
//var x = _minio.GetObjectMetadata(bucket, objectKey);
|
|
|
|
|
|
//TotalSize = x.Result.Size;
|
|
|
|
|
|
FileSize = fileSize;
|
2025-04-10 13:17:39 +08:00
|
|
|
|
PauseCommand = new CustomCommand(OnPause);
|
|
|
|
|
|
CancelCommand = new CustomCommand(OnCancel);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-15 14:05:06 +08:00
|
|
|
|
public void RefreshProgress()
|
|
|
|
|
|
{
|
|
|
|
|
|
OnPropertyChanged(nameof(Progress));
|
|
|
|
|
|
OnPropertyChanged("Progress");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-10 13:17:39 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 下载
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="savePath"></param>
|
2025-04-12 13:23:12 +08:00
|
|
|
|
public async Task StartDownload()
|
2025-04-10 13:17:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
_cts = new CancellationTokenSource();
|
|
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2025-04-15 10:29:41 +08:00
|
|
|
|
var stat = await _minio.GetObjectMetadata(Bucket, ObjectKey);
|
|
|
|
|
|
// 获取对象信息
|
|
|
|
|
|
TotalSize = stat.Size;
|
|
|
|
|
|
FileETag = stat.ETag;
|
2025-04-12 13:23:12 +08:00
|
|
|
|
Status = "下载中";
|
|
|
|
|
|
var updateTask = new MinioDownloadTask
|
|
|
|
|
|
{
|
|
|
|
|
|
TaskId = TaskId,
|
2025-04-15 10:29:41 +08:00
|
|
|
|
Status = Status,
|
|
|
|
|
|
TotalSize = TotalSize,
|
|
|
|
|
|
FileETag = FileETag
|
2025-04-12 13:23:12 +08:00
|
|
|
|
};
|
2025-04-10 13:17:39 +08:00
|
|
|
|
|
2025-04-12 13:23:12 +08:00
|
|
|
|
using (var client = SqlSugarConfig.GetSqlSugarScope())
|
2025-04-10 13:17:39 +08:00
|
|
|
|
{
|
2025-04-12 13:23:12 +08:00
|
|
|
|
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
|
2025-04-10 13:17:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-04-12 16:24:15 +08:00
|
|
|
|
Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey}文件下载中...");
|
2025-04-12 13:23:12 +08:00
|
|
|
|
updateTask.Status = "下载中";
|
2025-04-15 10:29:41 +08:00
|
|
|
|
await _minio.DownLoadObjectWithCallBack(Bucket, ObjectKey, FilePath, FileETag,
|
|
|
|
|
|
(downloaded, total) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var progress = (double)downloaded / total * 100;
|
|
|
|
|
|
Downloaded = downloaded;
|
2025-04-15 11:04:26 +08:00
|
|
|
|
/*using (var client = SqlSugarConfig.GetSqlSugarScope())
|
2025-04-15 10:29:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
updateTask.Downloaded = downloaded;
|
|
|
|
|
|
client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
|
2025-04-15 11:04:26 +08:00
|
|
|
|
}*/
|
2025-04-15 14:05:06 +08:00
|
|
|
|
Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
|
{
|
|
|
|
|
|
// 在 UI 线程上更新属性
|
|
|
|
|
|
Progress = progress;
|
|
|
|
|
|
Console.WriteLine($"文件 {FileName} 进度 {Progress}");
|
|
|
|
|
|
RefreshProgress();
|
|
|
|
|
|
});
|
|
|
|
|
|
//Console.WriteLine($"文件 {FileName} 进度 {Progress}");
|
2025-04-15 10:29:41 +08:00
|
|
|
|
});
|
|
|
|
|
|
//await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, "");
|
2025-04-10 13:17:39 +08:00
|
|
|
|
Status = "已完成";
|
2025-04-12 13:23:12 +08:00
|
|
|
|
updateTask.Status = Status;
|
2025-04-14 17:05:48 +08:00
|
|
|
|
updateTask.FinishedTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
|
2025-04-12 13:23:12 +08:00
|
|
|
|
using (var client = SqlSugarConfig.GetSqlSugarScope())
|
|
|
|
|
|
{
|
|
|
|
|
|
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Console.WriteLine($"文件{ObjectKey}下载完成");
|
2025-04-10 13:17:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
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)
|
2025-04-15 14:05:06 +08:00
|
|
|
|
{
|
|
|
|
|
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
|
|
|
|
|
}
|
2025-04-10 13:17:39 +08:00
|
|
|
|
}
|