From a69e71b86b167a8e23055bb86cc3f2b8dd486469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E4=BC=9F?= <421281095@qq.com> Date: Thu, 10 Apr 2025 13:17:39 +0800 Subject: [PATCH] =?UTF-8?q?=20object=20=E4=B8=8B=E8=BD=BD=E5=8F=8A?= =?UTF-8?q?=E9=83=A8=E9=97=A8=E4=BC=A0=E8=BE=93=E9=A1=B5=E9=9D=A2=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Models/CustomCommand.cs | 25 ++++ Provider/SqlSugarConfig.cs | 2 +- Services/MinioDownloadTask.cs | 155 +++++++++++++++++++ View/Send/DownControl.xaml | 217 ++++++++++++++++++++++++--- View/StatusToButtonConverter.cs | 22 +++ ViewModel/Loyout/LoyoutViewModel.cs | 43 +++--- ViewModel/Send/DownViewModel.cs | 222 ++++++++++++++++++++++++++-- ViewModel/Sync/SyncViewModel.cs | 37 ++--- minio.db | Bin 20480 -> 73728 bytes 9 files changed, 637 insertions(+), 86 deletions(-) create mode 100644 Models/CustomCommand.cs create mode 100644 Services/MinioDownloadTask.cs create mode 100644 View/StatusToButtonConverter.cs diff --git a/Models/CustomCommand.cs b/Models/CustomCommand.cs new file mode 100644 index 0000000..0bce3bd --- /dev/null +++ b/Models/CustomCommand.cs @@ -0,0 +1,25 @@ +using System.Windows.Input; + +namespace Hopetry.Models; + +public class CustomCommand : ICommand +{ + private readonly Action _execute; + + public CustomCommand(Action execute) + { + _execute = execute; + } + + public bool CanExecute(object parameter) + { + return true; + } + + public event EventHandler CanExecuteChanged; + + public void Execute(object parameter) + { + _execute(); + } +} \ No newline at end of file diff --git a/Provider/SqlSugarConfig.cs b/Provider/SqlSugarConfig.cs index 11a0390..3982c46 100644 --- a/Provider/SqlSugarConfig.cs +++ b/Provider/SqlSugarConfig.cs @@ -14,7 +14,7 @@ namespace Hopetry.Provider { return new SqlSugarClient(new ConnectionConfig() { - ConnectionString = @"DataSource=E:\数据上传转存\sqlite\minio.db", // 数据库路径 + ConnectionString = @"DataSource=minio.db", // 数据库路径 DbType = DbType.Sqlite, // 数据库类型 IsAutoCloseConnection = true, // 自动释放 InitKeyType = InitKeyType.Attribute // 从实体特性中读取主键信息 diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs new file mode 100644 index 0000000..5a2f398 --- /dev/null +++ b/Services/MinioDownloadTask.cs @@ -0,0 +1,155 @@ +using System.Windows; +using System.Windows.Input; +using HeBianGu.Base.WpfBase; +using Hopetry.Models; +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; + + /// + /// + /// + private CancellationTokenSource _cts; + + /// + /// + /// + private ManualResetEventSlim _pauseEvent = new(true); + + // 任务属性(绑定到UI) + [SugarColumn(ColumnName = "task_id")] 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; private set; } = "等待中"; + + public string Progress + { + get { return TotalSize == 0 ? "0%" : $"{(Downloaded * 100 / TotalSize):0.0}%"; } + } + + // 命令 + public ICommand PauseCommand { get; } + public ICommand CancelCommand { get; } + + public MinioDownloadTask() + { + PauseCommand = new CustomCommand(OnPause); + CancelCommand = new CustomCommand(OnCancel); + } + public MinioDownloadTask(MinioService minio, string bucket, string objectKey) + { + _minio = minio; + Bucket = bucket; + ObjectKey = objectKey; + TaskId = Interlocked.Increment(ref _globalId); + FileName = Path.GetFileName(objectKey); + + PauseCommand = new CustomCommand(OnPause); + CancelCommand = new CustomCommand(OnCancel); + } + + /// + /// 下载 + /// + /// + public async Task StartDownload(string savePath) + { + Status = "初始化"; + _cts = new CancellationTokenSource(); + var tmpPath = $"{savePath}.download"; + + try + { + // 断点续传初始化 + if (File.Exists(tmpPath)) + Downloaded = new FileInfo(tmpPath).Length; + + // 获取文件信息 + var stat = await _minio.GetObjectMetadata(Bucket, ObjectKey); + TotalSize = stat.Size; + + if (Downloaded >= TotalSize) + { + Status = "已完成"; + return; + } + + // todo 下载逻辑 + Status = "已完成"; + } + 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)); + + private static int _globalId; +} \ No newline at end of file diff --git a/View/Send/DownControl.xaml b/View/Send/DownControl.xaml index 6c076f8..4b96d1e 100644 --- a/View/Send/DownControl.xaml +++ b/View/Send/DownControl.xaml @@ -18,12 +18,17 @@