diff --git a/Services/MinioDownloadTask.cs b/Services/MinioDownloadTask.cs
index 5d63252..749e99e 100644
--- a/Services/MinioDownloadTask.cs
+++ b/Services/MinioDownloadTask.cs
@@ -53,7 +53,7 @@ public class MinioDownloadTask : INotifyPropertyChanged
[SugarColumn(ColumnName = "file_path")]
public string FilePath { get; set; }
- [SugarColumn(ColumnName = "status")] public string Status { get; private set; } = "等待中";
+ [SugarColumn(ColumnName = "status")] public string Status { get; set; } = "等待中";
[SugarColumn(IsIgnore = true)]
public string Progress
@@ -70,13 +70,14 @@ public class MinioDownloadTask : INotifyPropertyChanged
CancelCommand = new CustomCommand(OnCancel);
}
- public MinioDownloadTask(MinioService minio, string bucket, string objectKey)
+ public MinioDownloadTask(MinioService minio, string bucket, string objectKey, string downDir)
{
+ Status = "等待中";
_minio = minio;
Bucket = bucket;
ObjectKey = objectKey;
FileName = Path.GetFileName(objectKey);
- FilePath = "f:\\dest";
+ FilePath = downDir;
PauseCommand = new CustomCommand(OnPause);
CancelCommand = new CustomCommand(OnCancel);
}
@@ -103,7 +104,7 @@ public class MinioDownloadTask : INotifyPropertyChanged
await client.Updateable(updateTask).IgnoreNullColumns().ExecuteCommandAsync();
}
- Console.WriteLine($"{ObjectKey}文件下载中...");
+ Console.WriteLine($"id {TaskId} path: {FilePath} key: {ObjectKey}文件下载中...");
updateTask.Status = "下载中";
await _minio.DownLoadObject(Bucket, ObjectKey, FilePath, "");
Status = "已完成";
diff --git a/View/Loyout/ExplorerControl.xaml b/View/Loyout/ExplorerControl.xaml
index b73b1ed..71558b8 100644
--- a/View/Loyout/ExplorerControl.xaml
+++ b/View/Loyout/ExplorerControl.xaml
@@ -27,8 +27,8 @@
-
+
+
diff --git a/ViewModel/Loyout/LoyoutViewModel.cs b/ViewModel/Loyout/LoyoutViewModel.cs
index 2b12360..c567fd8 100644
--- a/ViewModel/Loyout/LoyoutViewModel.cs
+++ b/ViewModel/Loyout/LoyoutViewModel.cs
@@ -1,4 +1,5 @@
-using System.ComponentModel;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Timers;
@@ -19,6 +20,7 @@ using Hopetry.ViewModel.Send;
using System.IO;
using System.Security.AccessControl;
using System.Diagnostics;
+using System.Net.Http.Json;
using Microsoft.WindowsAPICodePack.Dialogs;
using Hopetry.Models;
using Yitter.IdGenerator;
@@ -27,9 +29,11 @@ using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
using HeBianGu.Control.Explorer;
using Hopetry.Provider.Behaviors;
using System.Text;
+using Hopetry.Provider;
using Minio.ApiEndpoints;
using Minio.DataModel;
using Minio.DataModel.Args;
+using Newtonsoft.Json;
using Timer = System.Timers.Timer;
using System.Collections.ObjectModel;
using Hopetry.Provider;
@@ -41,6 +45,7 @@ namespace HeBianGu.App.Disk
{
private readonly FileUploadService _uploadService;
private string _path;
+
/// 说明
public string Path
{
@@ -54,6 +59,7 @@ namespace HeBianGu.App.Disk
private string _nearPath;
+
/// 说明
public string NearPath
{
@@ -67,6 +73,7 @@ namespace HeBianGu.App.Disk
private string _sharePath;
+
/// 说明
public string SharePath
{
@@ -79,7 +86,6 @@ namespace HeBianGu.App.Disk
}
-
protected override void Init()
{
Path = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
@@ -89,7 +95,8 @@ namespace HeBianGu.App.Disk
SharePath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
// LinkActions.Add(new LinkAction() { Action = "Near", Controller = "Loyout", DisplayName = "最近使用", Logo = "\xe6f3" });
- LinkActions.Add(new LinkAction() { Action = "Explorer", Controller = "Loyout", DisplayName = "全部文件", Logo = "" });
+ LinkActions.Add(new LinkAction()
+ { Action = "Explorer", Controller = "Loyout", DisplayName = "全部文件", Logo = "" });
// LinkActions.Add(new LinkAction() { Action = "Image", Controller = "Loyout", DisplayName = " 图片", Logo = "" });
// LinkActions.Add(new LinkAction() { Action = "Video", Controller = "Loyout", DisplayName = " 视频", Logo = "" });
// LinkActions.Add(new LinkAction() { Action = "Document", Controller = "Loyout", DisplayName = " 文档", Logo = "" });
@@ -100,21 +107,18 @@ namespace HeBianGu.App.Disk
//LinkActions.Add(new LinkAction() { Action = "Share", Controller = "Loyout", DisplayName = "我的分享", Logo = "\xe764" });
// LinkActions.Add(new LinkAction() { Action = "Near", Controller = "Loyout", DisplayName = "回收站", Logo = "\xe618" });
- Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
- {
- SelectLink = LinkActions[0];
- }));
-
+ Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Loaded,
+ new Action(() => { SelectLink = LinkActions[0]; }));
}
protected override void Loaded(string args)
{
-
}
-
+
#region 文件上传
+
private SendViewModel _sendViewModel;
private IConfiguration config;
private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
@@ -131,8 +135,11 @@ namespace HeBianGu.App.Disk
public ICommand UploadCommand { get; }
public ICommand UploadCommand1 { get; }
- public ICommand CreateFolderCommand { get; }
- public ICommand DeleteFolderCommand { get; }
+ public ICommand CreateFolderCommand { get; }
+ public ICommand DownloadCommand { get; set; }
+
+ public ICommand DeleteFolderCommand { get; }
+
//public ICommand SelectItemsCommand { get; }
public LoyoutViewModel(SendViewModel sendViewModel)
{
@@ -142,15 +149,38 @@ namespace HeBianGu.App.Disk
UploadCommand1 = new AsyncRelayCommand(async () => await UploadFile1());
CreateFolderCommand = new AsyncRelayCommand(async () => await CreateNewFolderAsync());
DeleteFolderCommand = new AsyncRelayCommand(async () => await DeleteSelectedItemsAsync());
+ DownloadCommand = new AsyncRelayCommand(async () => await DoDownloadCommand());
//SelectItemsCommand = new AsyncRelayCommand(async () => await RelayCommand(SelectItem)SelectItem());
// 初始化Timer
_progressTimer = new Timer(1000);
_progressTimer.Elapsed += UpdateProgress;
- _sendViewModel.UpLoadItems.CollectionChanged += (s, e) =>
- {
- _sendViewModel.UpdateUploadingItems();
- };
+ _sendViewModel.UpLoadItems.CollectionChanged += (s, e) => { _sendViewModel.UpdateUploadingItems(); };
}
+
+ private async Task DoDownloadCommand()
+ {
+ // todo 当为文件时,处理
+ var selectedItems = _selectedItems;
+ // 清除选中
+ //SelectedItems = [];
+ foreach (var item in selectedItems)
+ {
+ if (item is MinIOFileModel file)
+ {
+ var temp = (MinIOFileInfo)file.Model;
+ var objectKey = temp.FullName.Replace(temp.BucketName + "/", "");
+ ViewModelLocator.DownViewModel.AddTask(temp.BucketName, objectKey);
+ }
+
+ if (item is MinIODirectoryModel dir)
+ {
+ Console.WriteLine("建设中...");
+ //return ((MinIODirectoryInfo)dir.Model).BucketName;
+ }
+ }
+
+ }
+
// 添加设置Behavior的方法
public void SetExplorerBehavior(ExplorerMinIOBehavior behavior)
{
@@ -171,10 +201,7 @@ namespace HeBianGu.App.Disk
double totalBytes = _sendViewModel.UpLoadItems.Sum(r => r.Double1);
double progress = Math.Round((currentBytes / totalBytes) * 100, 2);
- Application.Current.Dispatcher.Invoke(() =>
- {
- _sendViewModel.Progress = progress;
- });
+ Application.Current.Dispatcher.Invoke(() => { _sendViewModel.Progress = progress; });
}
}
@@ -229,6 +256,7 @@ namespace HeBianGu.App.Disk
var ut = CreateUploadItem(filePath, System.IO.Path.GetFileName(filePath));
_sendViewModel.UpLoadItems.Add(ut);
}
+
_uploadCount = _sendViewModel.UpLoadItems.Count;
//_uploadCount = _sendViewModel.UpLoadItems.Count;
_completeCount = _sendViewModel.UpLoadItems.Where(r => r.Value3 == "已完成").Count();
@@ -267,10 +295,12 @@ namespace HeBianGu.App.Disk
foreach (string filePath in files)
{
- string relativePath = folderName + "/" + filePath.Substring(folderPath.Length + 1).Replace('\\', '/');
+ string relativePath =
+ folderName + "/" + filePath.Substring(folderPath.Length + 1).Replace('\\', '/');
var ut = CreateUploadItem(filePath, relativePath);
_sendViewModel.UpLoadItems.Add(ut);
}
+
_uploadCount = _sendViewModel.UpLoadItems.Count;
_completeCount = _sendViewModel.UpLoadItems.Where(r => r.Value3 == "已完成").Count();
_sendViewModel.FileCount = _completeCount + "/" + _uploadCount;
@@ -287,27 +317,27 @@ namespace HeBianGu.App.Disk
private UpLoadItems CreateUploadItem(string filePath, string objectName)
{
FileInfo fileInfo = new FileInfo(filePath);
- string sizeText = fileInfo.Length < 1024 * 1024 ?
- $"{Math.Ceiling((decimal)fileInfo.Length / 1024)}KB" :
- $"{Math.Ceiling((decimal)fileInfo.Length / (1024 * 1024))}MB";
+ string sizeText = fileInfo.Length < 1024 * 1024
+ ? $"{Math.Ceiling((decimal)fileInfo.Length / 1024)}KB"
+ : $"{Math.Ceiling((decimal)fileInfo.Length / (1024 * 1024))}MB";
//写入数据库
- FUpload fp= new FUpload();
- fp.Id= Guid.NewGuid().ToString();
- fp.FileName= objectName;
+ FUpload fp = new FUpload();
+ fp.Id = Guid.NewGuid().ToString();
+ fp.FileName = objectName;
fp.FileSize = fileInfo.Length;
fp.FilePath = filePath;
fp.FileType = fileInfo.Extension;
- fp.CreateTime=DateTime.Now;
- fp.IsComplete=false;
- fp.FileSizeText=sizeText;
+ fp.CreateTime = DateTime.Now;
+ fp.IsComplete = false;
+ fp.FileSizeText = sizeText;
if (_uploadService.AddFile(fp))
{
return new UpLoadItems
{
Value = System.IO.Path.GetFileName(filePath),
Value3 = "等待上传",
- Value4 = fp.Id, //唯一标识,与数据库一致
+ Value4 = fp.Id, //唯一标识,与数据库一致
Value5 = filePath,
Value6 = objectName,
Double1 = fileInfo.Length,
@@ -377,8 +407,8 @@ namespace HeBianGu.App.Disk
{
ut.Bool1 = true;
var builder = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("global.json", optional: false, reloadOnChange: true);
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("global.json", optional: false, reloadOnChange: true);
// 构建配置
var config = builder.Build();
// 从配置获取MinIO设置更安全
@@ -386,10 +416,9 @@ namespace HeBianGu.App.Disk
.WithEndpoint(config["Minio:Endpoint"])
.WithCredentials(config["Minio:AccessKey"], config["Minio:SecretKey"])
.Build();
-
+
try
{
-
string bucketName = config["Minio:BucketName"];
// 确保桶存在
@@ -411,9 +440,9 @@ namespace HeBianGu.App.Disk
int slashIndex = ut.Value1.IndexOf('/');
string sizePart = ut.Value1.Substring(slashIndex);
- string transferredPart = trans < 1024 * 1024 ?
- $"{Math.Ceiling((decimal)trans / 1024)}KB" :
- $"{Math.Ceiling((decimal)trans / (1024 * 1024))}MB";
+ string transferredPart = trans < 1024 * 1024
+ ? $"{Math.Ceiling((decimal)trans / 1024)}KB"
+ : $"{Math.Ceiling((decimal)trans / (1024 * 1024))}MB";
ut.Value1 = $"{transferredPart}{sizePart}";
if (progressReport.Percentage == 100)
@@ -425,7 +454,7 @@ namespace HeBianGu.App.Disk
ut.Value3 = "已完成";
_sendViewModel.UpdateUploadingItems();
_completeCount++;
- _sendViewModel.FileCount=_completeCount+"/"+_uploadCount;
+ _sendViewModel.FileCount = _completeCount + "/" + _uploadCount;
}
else
{
@@ -440,14 +469,11 @@ namespace HeBianGu.App.Disk
.WithFileName(ut.Value5)
.WithProgress(progress);
- await client.PutObjectAsync(putObjectArgs);
+ await client.PutObjectAsync(putObjectArgs);
}
catch (Exception ex)
{
- Application.Current.Dispatcher.Invoke(() =>
- {
- ut.Value3 = $"上传失败: {ex.Message}";
- });
+ Application.Current.Dispatcher.Invoke(() => { ut.Value3 = $"上传失败: {ex.Message}"; });
}
}
@@ -462,10 +488,13 @@ namespace HeBianGu.App.Disk
MessageBox.Show($"关机失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
+
#endregion
#region 文件列表
+
private string _currentMinIOPath;
+
/// 说明CurrentMinIOPath
public string CurrentMinIOPath
{
@@ -495,7 +524,6 @@ namespace HeBianGu.App.Disk
}
-
public ObservableCollection Items { get; } = new ObservableCollection();
private async Task CreateNewFolderAsync()
@@ -530,8 +558,8 @@ namespace HeBianGu.App.Disk
public async Task CreateMinIOFolder(string folderName)
{
var builder = new ConfigurationBuilder()
- .SetBasePath(Directory.GetCurrentDirectory())
- .AddJsonFile("global.json", optional: false, reloadOnChange: true);
+ .SetBasePath(Directory.GetCurrentDirectory())
+ .AddJsonFile("global.json", optional: false, reloadOnChange: true);
// 构建配置
var config = builder.Build();
// 从配置获取MinIO设置更安全
@@ -566,7 +594,7 @@ namespace HeBianGu.App.Disk
.WithBucket(bucketName)
.WithObject(prefix + folderName)
.WithStreamData(emptyStream)
- .WithObjectSize(1) // 必须设置为0
+ .WithObjectSize(1) // 必须设置为0
.WithContentType("application/x-directory"));
}
@@ -594,18 +622,27 @@ namespace HeBianGu.App.Disk
return CurrentMinIOPath.Substring(CurrentMinIOPath.IndexOf('/') + 1);
}
+
#endregion
#region 删除文件夹
+
private ObservableCollection _selectedItems = new ObservableCollection();
+
public ObservableCollection SelectedItems
{
get { return _selectedItems; }
- set { _selectedItems = value; RaisePropertyChanged(); }
+ set
+ {
+ _selectedItems = value;
+ RaisePropertyChanged();
+ }
}
private ICommand _selectItemsCommand;
- public ICommand SelectItemsCommand => _selectItemsCommand ?? (_selectItemsCommand = new RelayCommand(SelectItem));
+
+ public ICommand SelectItemsCommand => _selectItemsCommand ??
+ (_selectItemsCommand = new RelayCommand(SelectItem));
private void SelectItem(SystemInfoModel item)
{
@@ -620,6 +657,7 @@ namespace HeBianGu.App.Disk
SelectedItems.Add(item);
}
}
+
private async Task DeleteSelectedItemsAsync()
{
try
@@ -720,7 +758,6 @@ namespace HeBianGu.App.Disk
}
#endregion
-
}
internal class DataFileViewModel : ObservableSourceViewModel
@@ -728,7 +765,6 @@ namespace HeBianGu.App.Disk
protected override void Init()
{
base.Init();
-
}
}
-}
+}
\ No newline at end of file
diff --git a/ViewModel/Send/DownViewModel.cs b/ViewModel/Send/DownViewModel.cs
index b4c5be5..127b1ad 100644
--- a/ViewModel/Send/DownViewModel.cs
+++ b/ViewModel/Send/DownViewModel.cs
@@ -2,7 +2,6 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
-using System.IO;
using System.Windows.Data;
using System.Windows.Input;
using HeBianGu.Base.WpfBase;
@@ -11,7 +10,6 @@ using Hopetry.Models;
using Hopetry.Provider;
using Hopetry.Services;
using Newtonsoft.Json;
-using SqlSugar;
namespace Hopetry.ViewModel.Send;
@@ -22,13 +20,12 @@ public class DownViewModel : MvcViewModelBase
public RelayCommand OpenDownItemFolder { get; set; }
private readonly ConcurrentQueue _taskQueue = new();
- private SemaphoreSlim _concurrencySemaphore;
+ private SemaphoreSlim _semaphore;
private CancellationTokenSource _processingCts = new();
public int count { get; set; }
-
- private SemaphoreSlim _semaphore;
private readonly ReaderWriterLockSlim _lock = new();
+
///
/// 全部任务动态标题
@@ -70,7 +67,7 @@ public class DownViewModel : MvcViewModelBase
}
// 绑定属性
- public ObservableCollection AllTasks { get; set; } = new();
+ public ObservableCollection AllTasks { get; set; }
public ICollectionView RunningTasksView { get; set; }
@@ -106,27 +103,23 @@ public class DownViewModel : MvcViewModelBase
// 命令
public ICommand AddTaskCommand { get; set; }
public ICommand ClearFinishedCommand { get; }
-
+ private readonly ISerializerService _serializerService;
///
/// 构造函数
///
///
- public DownViewModel(MinioService minioService, SemaphoreSlim semaphore)
+ public DownViewModel(MinioService minioService, ISerializerService serializerService)
{
+ _serializerService = serializerService;
_minioService = minioService;
- _semaphore = semaphore;
Console.WriteLine("初始化DownViewModel");
using var client = SqlSugarConfig.GetSqlSugarScope();
var data = client.Ado.SqlQuery($"select * from download_task");
- //DownItems = new ObservableCollection(data);
AllTasks = new ObservableCollection(data);
AllTaskHeader = $"全部({AllTasks.Count})";
//Console.WriteLine(JsonConvert.SerializeObject(data));
OpenDownItemFolder = new RelayCommand(DoOpenDownItemFolder);
- // 命令初始化
- // AddTaskCommand = new RelayCommand(AddTask, CanAddTask);
- // 修正:使用 CollectionViewSource 确保通知
var cvsRunning = new CollectionViewSource { Source = AllTasks };
cvsRunning.Filter += (s, e) =>
{
@@ -142,15 +135,7 @@ public class DownViewModel : MvcViewModelBase
e.Accepted = b;
};
FinishedTasksView = cvsFinished.View;
- if (FinishedTasksView is ListCollectionView finishListView)
- {
- FinishedTaskHeader = $"已完成({finishListView.Count})";
- }
-
- if (RunningTasksView is ListCollectionView runningListView)
- {
- RunningTaskHeader = $"下载中({runningListView.Count})";
- }
+ RefreshViewHeader();
// 关键:订阅数据源变更事件,强制视图刷新
AllTasks.CollectionChanged += (s, e) =>
@@ -166,41 +151,51 @@ public class DownViewModel : MvcViewModelBase
// 启动任务处理线程
_semaphore = new SemaphoreSlim(_maxConcurrent);
- // 启动任务处理线程
- _concurrencySemaphore = new SemaphoreSlim(_maxConcurrent);
new Thread(ProcessTasksLoop) { IsBackground = true }.Start();
-
-
- AddTaskCommand = new ActionCommand(AddTask);
+ //AddTaskCommand = new ActionCommand(AddTask);
}
- private void ProcessTasksLoop()
+ private void RefreshViewHeader()
{
+ if (FinishedTasksView is ListCollectionView finishListView)
+ {
+ FinishedTaskHeader = $"已完成({finishListView.Count})";
+ }
+
+ if (RunningTasksView is ListCollectionView runningListView)
+ {
+ RunningTaskHeader = $"下载中({runningListView.Count})";
+ }
+ }
+
+ private async void ProcessTasksLoop()
+ {
+ int c1 = 1;
while (!_processingCts.IsCancellationRequested)
{
- _semaphore.WaitAsync();
- // 按当前并发数启动任务
- for (int i = 0; i < _maxConcurrent; i++)
+ await _semaphore.WaitAsync();
+ Console.WriteLine("获得下载许可");
+ if (_taskQueue.TryDequeue(out var task))
{
- if (_taskQueue.TryDequeue(out var task))
- {
- // 启动新线程执行下载任务
- _ = Task.Run(() => ExecuteTaskAsync(task));
- }
+ Console.WriteLine($"开启下载任务:{c1++}");
+ // 启动新线程执行下载任务
+ // _ = Task.Run(() => ExecuteTaskAsync(task));
+ _ = ExecuteTaskAsync(task).ContinueWith(_ => _semaphore.Release());
}
Thread.Sleep(100);
}
}
- private void AddTask()
+ public void AddTask(string bucketName, string objectKey)
{
- string[] objectKeys = { "demo/06.mp4", "demo/07.mp4", "demo/08.mp4", "demo/10.mp4" };
- var task = new MinioDownloadTask(_minioService, "demo", objectKeys[count++]);
+ var downDir = ViewModelLocator.SyncViewModel.SyncDir;
+ var task = new MinioDownloadTask(_minioService, bucketName, objectKey,downDir);
using var client = SqlSugarConfig.GetSqlSugarScope();
client.Insertable(task).ExecuteCommandIdentityIntoEntity();
AllTasks.Add(task);
_taskQueue.Enqueue(task);
+ RefreshViewHeader();
}
@@ -209,25 +204,30 @@ public class DownViewModel : MvcViewModelBase
try
{
await task.StartDownload();
- // todo 任务完成下载
+ var x = AllTasks.IndexOf(task);
+ var temp = AllTasks[x];
+ temp.Status = "已完成";
+ Console.WriteLine($"所有任务取出任务id {temp.TaskId} 完成任务id:{task.TaskId}" );
+ Console.WriteLine($"完成任务在全部任务中的位置 :{x}");
+ RefreshViewHeader();
+ Console.WriteLine($"异步下载完成:{task.FileName}");
}
finally
{
- _semaphore.Release();
}
}
private void AdjustConcurrency()
{
- lock (_concurrencySemaphore)
+ lock (_semaphore)
{
// 调整信号量容量
- var delta = _maxConcurrent - _concurrencySemaphore.CurrentCount;
+ var delta = _maxConcurrent - _semaphore.CurrentCount;
if (delta > 0)
{
for (int i = 0; i < delta; i++)
{
- _concurrencySemaphore.Release();
+ _semaphore.Release();
}
}
}
diff --git a/minio.db b/minio.db
index 7d0493b..d577e09 100644
Binary files a/minio.db and b/minio.db differ