Compare commits

...

2 Commits

2 changed files with 186 additions and 82 deletions

View File

@ -57,6 +57,7 @@ namespace Hopetry.Provider.Behaviors
#region 字段和初始化 #region 字段和初始化
private IMinioClient _minioClient; private IMinioClient _minioClient;
private bool _isLocalHistoryRefresh; private bool _isLocalHistoryRefresh;
private bool _isNavigationCommand = false;
protected override void OnAttached() protected override void OnAttached()
{ {
base.OnAttached(); base.OnAttached();
@ -74,19 +75,11 @@ namespace Hopetry.Provider.Behaviors
historyDescriptor.AddValueChanged(AssociatedObject, OnHistoryChanged); historyDescriptor.AddValueChanged(AssociatedObject, OnHistoryChanged);
// 初始加载MinIO内容 // 初始加载MinIO内容
if (UseMinIO) if (UseMinIO )
{ {
Dispatcher.BeginInvoke((Action)(() => Dispatcher.BeginInvoke((Action)(() =>
{ {
//var initialPath = string.IsNullOrEmpty(AssociatedObject.CurrentPath) ?
// "" : AssociatedObject.CurrentPath;
RefreshMinIOPath(AssociatedObject.CurrentPath); RefreshMinIOPath(AssociatedObject.CurrentPath);
//// 更新CurrentPath如果为空
//if (string.IsNullOrEmpty(AssociatedObject.CurrentPath))
//{
// AssociatedObject.CurrentPath = initialPath;
//}
}), DispatcherPriority.Loaded); }), DispatcherPriority.Loaded);
} }
@ -128,6 +121,8 @@ namespace Hopetry.Provider.Behaviors
dataGrid.BeginningEdit += DataGrid_BeginningEdit; dataGrid.BeginningEdit += DataGrid_BeginningEdit;
} }
AssociatedObject.Loaded += OnExplorerLoaded; AssociatedObject.Loaded += OnExplorerLoaded;
// 监听导航命令
CommandManager.AddPreviewExecutedHandler(AssociatedObject, OnPreviewCommandExecuted);
} }
protected override void OnDetaching() protected override void OnDetaching()
@ -146,7 +141,7 @@ namespace Hopetry.Provider.Behaviors
{ {
dataGrid.CellEditEnding -= DataGrid_CellEditEnding; dataGrid.CellEditEnding -= DataGrid_CellEditEnding;
} }
CommandManager.RemovePreviewExecutedHandler(AssociatedObject, OnPreviewCommandExecuted);
base.OnDetaching(); base.OnDetaching();
} }
@ -166,7 +161,15 @@ namespace Hopetry.Provider.Behaviors
}), DispatcherPriority.ContextIdle); }), DispatcherPriority.ContextIdle);
} }
} }
private void OnPreviewCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
if (e.Command == Explorer.Previous || e.Command == Explorer.Next)
{
_isNavigationCommand = true;
Dispatcher.BeginInvoke(new Action(() => _isNavigationCommand = false),
DispatcherPriority.ApplicationIdle);
}
}
private void OnCurrentPathChanged(object sender, EventArgs e) private void OnCurrentPathChanged(object sender, EventArgs e)
{ {
if (UseMinIO) if (UseMinIO)
@ -177,7 +180,7 @@ namespace Hopetry.Provider.Behaviors
private void OnHistoryChanged(object sender, EventArgs e) private void OnHistoryChanged(object sender, EventArgs e)
{ {
// Track when history is changed externally // 只有当历史记录变更不是由导航触发时才标记为本地刷新
_isLocalHistoryRefresh = true; _isLocalHistoryRefresh = true;
} }
@ -222,7 +225,7 @@ namespace Hopetry.Provider.Behaviors
} }
// Update history if this wasn't triggered by a history navigation // Update history if this wasn't triggered by a history navigation
if (!_isLocalHistoryRefresh && !string.IsNullOrEmpty(path)) if (!_isNavigationCommand && !string.IsNullOrEmpty(path))
{ {
UpdateHistory(path); UpdateHistory(path);
} }
@ -300,37 +303,92 @@ namespace Hopetry.Provider.Behaviors
}).ToList(); }).ToList();
} }
//private void UpdateHistory(string path)
//{
// if (string.IsNullOrEmpty(path))
// {
// // 根路径时创建一个特殊的目录模型
// var rootItem = new DirectoryModel(new MinIODirectoryInfo("", "", true, DateTime.Now))
// {
// DisplayName = RootDisplayName
// };
// AssociatedObject.History.Insert(0, rootItem);
// }
// else
// {
// var parts = path.Split(new[] { '/' }, 2);
// var bucketName = parts[0];
// var prefix = parts.Length > 1 ? parts[1] : null;
// var dirInfo = new MinIODirectoryInfo(bucketName, prefix, false, DateTime.Now);
// var historyItem = new DirectoryModel(dirInfo);
// if (AssociatedObject.History.FirstOrDefault()?.Model?.FullName != path)
// {
// AssociatedObject.History.Insert(0, historyItem);
// AssociatedObject.History = AssociatedObject.History
// .Take(ExplorerSetting.Instance.HistCapacity)
// .ToObservable();
// }
// }
// AssociatedObject.HistorySelectedItem = AssociatedObject.History.FirstOrDefault();
//}
private void UpdateHistory(string path) private void UpdateHistory(string path)
{ {
if (string.IsNullOrEmpty(path)) if (AssociatedObject == null || _isNavigationCommand)
return;
try
{ {
// 根路径时创建一个特殊的目录模型 // 检查是否已经是历史记录中的第一个项目
var rootItem = new DirectoryModel(new MinIODirectoryInfo("", "", true, DateTime.Now)) var firstHistoryItem = AssociatedObject.History.FirstOrDefault();
if (firstHistoryItem?.Model?.FullName == path)
return;
// 创建适当的目录模型
DirectoryModel historyItem;
if (string.IsNullOrEmpty(path) || path == RootDisplayName)
{ {
DisplayName = RootDisplayName // 根路径时创建一个特殊的目录模型
}; historyItem = new DirectoryModel(new MinIODirectoryInfo("", "", true, DateTime.Now))
AssociatedObject.History.Insert(0, rootItem); {
} DisplayName = RootDisplayName
else };
{
var parts = path.Split(new[] { '/' }, 2);
var bucketName = parts[0];
var prefix = parts.Length > 1 ? parts[1] : null;
var dirInfo = new MinIODirectoryInfo(bucketName, prefix, false, DateTime.Now);
var historyItem = new DirectoryModel(dirInfo);
if (AssociatedObject.History.FirstOrDefault()?.Model?.FullName != path)
{
AssociatedObject.History.Insert(0, historyItem);
AssociatedObject.History = AssociatedObject.History
.Take(ExplorerSetting.Instance.HistCapacity)
.ToObservable();
} }
} else
{
var parts = path.Split(new[] { '/' }, 2);
var bucketName = parts[0];
var prefix = parts.Length > 1 ? parts[1] : null;
AssociatedObject.HistorySelectedItem = AssociatedObject.History.FirstOrDefault(); var dirInfo = new MinIODirectoryInfo(bucketName, prefix, false, DateTime.Now);
historyItem = new DirectoryModel(dirInfo);
}
// 更新历史记录
_isLocalHistoryRefresh = true; // 防止递归触发
var newHistory = AssociatedObject.History.ToList();
newHistory.Insert(0, historyItem);
// 限制历史记录数量
AssociatedObject.History = newHistory
.Take(ExplorerSetting.Instance.HistCapacity)
.ToObservable();
AssociatedObject.HistorySelectedItem = AssociatedObject.History.FirstOrDefault();
}
catch (Exception ex)
{
Debug.WriteLine($"UpdateHistory error: {ex.Message}");
}
finally
{
_isLocalHistoryRefresh = false;
}
} }
#endregion #endregion

View File

@ -27,6 +27,7 @@ namespace HeBianGu.App.Disk
[ViewModel("Loyout")] [ViewModel("Loyout")]
internal class LoyoutViewModel : MvcViewModelBase internal class LoyoutViewModel : MvcViewModelBase
{ {
#region 参数定义及初始化
private readonly FileUploadService _uploadService; private readonly FileUploadService _uploadService;
private string _path; private string _path;
@ -95,8 +96,10 @@ namespace HeBianGu.App.Disk
{ {
GetCompletedFiles(); GetCompletedFiles();
} }
#endregion
#region 文件上传 #region 文件上传
#region 参数定义
private SendViewModel _sendViewModel; private SendViewModel _sendViewModel;
private IConfiguration config; private IConfiguration config;
private SemaphoreSlim _semaphore = new SemaphoreSlim(5); private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
@ -138,31 +141,9 @@ namespace HeBianGu.App.Disk
//加载上传完成列表 //加载上传完成列表
GetCompletedFiles(); GetCompletedFiles();
} }
#endregion
private async Task DoDownloadCommand() #region 行为方法
{
// 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,temp.Size);
}
if (item is MinIODirectoryModel dir)
{
Console.WriteLine("建设中...");
//return ((MinIODirectoryInfo)dir.Model).BucketName;
}
}
}
// 添加设置Behavior的方法 // 添加设置Behavior的方法
public void SetExplorerBehavior(ExplorerMinIOBehavior behavior) public void SetExplorerBehavior(ExplorerMinIOBehavior behavior)
{ {
@ -173,6 +154,9 @@ namespace HeBianGu.App.Disk
{ {
_minioBehavior = behavior; _minioBehavior = behavior;
} }
#endregion
#region 更新总进度条 每隔1s更新一次
private void UpdateProgress(object sender, System.Timers.ElapsedEventArgs e) private void UpdateProgress(object sender, System.Timers.ElapsedEventArgs e)
{ {
lock (_timerLock) lock (_timerLock)
@ -210,7 +194,10 @@ namespace HeBianGu.App.Disk
} }
} }
} }
#endregion
#region 上传执行
//多文件上传
private async Task UploadFile() private async Task UploadFile()
{ {
var openFileDialog = new OpenFileDialog var openFileDialog = new OpenFileDialog
@ -233,9 +220,22 @@ namespace HeBianGu.App.Disk
return; return;
} }
//判断是否存在上传路径
string bucketName = GetCurrentBucket();
if (string.IsNullOrEmpty(bucketName))
{
MessageBox.Show("请选择上传路径");
return;
}
foreach (string filePath in newFiles) foreach (string filePath in newFiles)
{ {
var ut = CreateUploadItem(filePath, System.IO.Path.GetFileName(filePath)); var fix = GetCurrentPrefix(); //获取当前所在的文件夹路径,除桶之外的
string str = System.IO.Path.GetFileName(filePath);
if (!string.IsNullOrEmpty(fix))
{
str = fix + "/" + System.IO.Path.GetFileName(filePath);
}
var ut = CreateUploadItem(filePath, str);
_sendViewModel.UpLoadItems.Add(ut); _sendViewModel.UpLoadItems.Add(ut);
} }
@ -253,6 +253,7 @@ namespace HeBianGu.App.Disk
} }
} }
//文件夹上传
private async Task UploadFile1() private async Task UploadFile1()
{ {
var dialog = new CommonOpenFileDialog var dialog = new CommonOpenFileDialog
@ -275,11 +276,23 @@ namespace HeBianGu.App.Disk
MessageBox.Show("没有新文件需要上传或文件已在上传队列中"); MessageBox.Show("没有新文件需要上传或文件已在上传队列中");
return; return;
} }
//判断是否存在上传路径
string bucketName = GetCurrentBucket();
if (string.IsNullOrEmpty(bucketName))
{
MessageBox.Show("请选择上传路径");
return;
}
foreach (string filePath in files) foreach (string filePath in files)
{ {
var fix = GetCurrentPrefix(); //获取当前所在的文件夹路径,除桶之外的
string relativePath = string relativePath =
folderName + "/" + filePath.Substring(folderPath.Length + 1).Replace('\\', '/'); folderName + "/" + filePath.Substring(folderPath.Length + 1).Replace('\\', '/');
if (!string.IsNullOrEmpty(fix))
{
relativePath = fix + "/" + folderName + "/" + filePath.Substring(folderPath.Length + 1).Replace('\\', '/');
}
var ut = CreateUploadItem(filePath, relativePath); var ut = CreateUploadItem(filePath, relativePath);
_sendViewModel.UpLoadItems.Add(ut); _sendViewModel.UpLoadItems.Add(ut);
} }
@ -297,6 +310,7 @@ namespace HeBianGu.App.Disk
} }
} }
//创建上传列表
private UpLoadItems CreateUploadItem(string filePath, string objectName) private UpLoadItems CreateUploadItem(string filePath, string objectName)
{ {
FileInfo fileInfo = new FileInfo(filePath); FileInfo fileInfo = new FileInfo(filePath);
@ -321,8 +335,8 @@ namespace HeBianGu.App.Disk
Value = System.IO.Path.GetFileName(filePath), Value = System.IO.Path.GetFileName(filePath),
Value3 = "等待上传", Value3 = "等待上传",
Value4 = fp.Id, //唯一标识,与数据库一致 Value4 = fp.Id, //唯一标识,与数据库一致
Value5 = filePath, Value5 = filePath, //文件名称
Value6 = objectName, Value6 = objectName, //文件地址
Double1 = fileInfo.Length, Double1 = fileInfo.Length,
Double2 = 0.0, Double2 = 0.0,
Bool1 = false, Bool1 = false,
@ -335,6 +349,7 @@ namespace HeBianGu.App.Disk
} }
} }
//创建上传任务
private async Task ProcessUploadTasks() private async Task ProcessUploadTasks()
{ {
_isUploading = true; _isUploading = true;
@ -388,6 +403,7 @@ namespace HeBianGu.App.Disk
} }
} }
//上传具体执行
private async Task UploadFileToMinIOWithProgress(UpLoadItems ut) private async Task UploadFileToMinIOWithProgress(UpLoadItems ut)
{ {
ut.Bool1 = true; ut.Bool1 = true;
@ -404,7 +420,8 @@ namespace HeBianGu.App.Disk
try try
{ {
string bucketName = config["Minio:BucketName"]; //string bucketName = config["Minio:BucketName"];
string bucketName = GetCurrentBucket();
// 确保桶存在 // 确保桶存在
var beArgs = new BucketExistsArgs().WithBucket(bucketName); var beArgs = new BucketExistsArgs().WithBucket(bucketName);
@ -441,6 +458,8 @@ namespace HeBianGu.App.Disk
_completeCount++; _completeCount++;
_sendViewModel.FileCount = _completeCount + "/" + _uploadCount; _sendViewModel.FileCount = _completeCount + "/" + _uploadCount;
UpdateFileCounts(); UpdateFileCounts();
// 刷新当前目录
_explorerBehavior?.RefreshMinIOPath(CurrentMinIOPath);
} }
else else
{ {
@ -462,7 +481,10 @@ namespace HeBianGu.App.Disk
Application.Current.Dispatcher.Invoke(() => { ut.Value3 = $"上传失败: {ex.Message}"; }); Application.Current.Dispatcher.Invoke(() => { ut.Value3 = $"上传失败: {ex.Message}"; });
} }
} }
#endregion
#region 其他
//关机
private void Shutdown() private void Shutdown()
{ {
try try
@ -475,11 +497,13 @@ namespace HeBianGu.App.Disk
} }
} }
//更新上传进行中及上传完成列表
private void UpdateFileCounts() private void UpdateFileCounts()
{ {
_sendViewModel.UploadingCount = _sendViewModel.UploadingItems.Count; _sendViewModel.UploadingCount = _sendViewModel.UploadingItems.Count;
_sendViewModel.CompleteCount = _sendViewModel.CompleteItems.Count; _sendViewModel.CompleteCount = _sendViewModel.CompleteItems.Count;
} }
//加载初始完成文件 //加载初始完成文件
public void GetCompletedFiles() public void GetCompletedFiles()
{ {
@ -502,11 +526,36 @@ namespace HeBianGu.App.Disk
_sendViewModel.CompleteCount=regionCount; _sendViewModel.CompleteCount=regionCount;
} }
#endregion #endregion
#endregion
#region 文件下载
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, temp.Size);
}
if (item is MinIODirectoryModel dir)
{
Console.WriteLine("建设中...");
//return ((MinIODirectoryInfo)dir.Model).BucketName;
}
}
}
#endregion
#region 文件列表 #region 文件列表
private string _currentMinIOPath; private string _currentMinIOPath;
/// <summary> 说明CurrentMinIOPath </summary> /// <summary> 说明CurrentMinIOPath </summary>
public string CurrentMinIOPath public string CurrentMinIOPath
{ {
@ -526,25 +575,22 @@ namespace HeBianGu.App.Disk
_currentMinIOPath = newPath; _currentMinIOPath = newPath;
RaisePropertyChanged("CurrentMinIOPath"); RaisePropertyChanged("CurrentMinIOPath");
// 强制刷新导航栏 //// 强制刷新导航栏
if (_explorerBehavior != null) //if (_explorerBehavior != null)
{ //{
_explorerBehavior.RefreshMinIOPath(newPath); // _explorerBehavior.RefreshMinIOPath(newPath);
} //}
} }
} }
} }
public ObservableCollection<SystemInfoModel> Items { get; } = new ObservableCollection<SystemInfoModel>(); public ObservableCollection<SystemInfoModel> Items { get; } = new ObservableCollection<SystemInfoModel>();
//Explorer创建新建文件夹并可编辑
private async Task CreateNewFolderAsync() private async Task CreateNewFolderAsync()
{ {
try try
{ {
//// 获取当前绑定的集合
//var itemsSource = AssociatedObject.ItemsSource as ObservableCollection<SystemInfoModel>;
//if (itemsSource == null) return;
// 创建新的文件夹模型 // 创建新的文件夹模型
var newFolder = new MinIODirectoryModel( var newFolder = new MinIODirectoryModel(
new MinIODirectoryInfo(GetCurrentBucket(), "新建文件夹/", false, DateTime.Now)) new MinIODirectoryInfo(GetCurrentBucket(), "新建文件夹/", false, DateTime.Now))
@ -552,9 +598,6 @@ namespace HeBianGu.App.Disk
IsRenaming = false // 设置为可编辑状态 IsRenaming = false // 设置为可编辑状态
}; };
//// 添加到集合最前面
//itemsSource.Insert(0, newFolder);
// 通知行为类开始编辑 // 通知行为类开始编辑
_explorerBehavior?.BeginEditNewFolder(newFolder); _explorerBehavior?.BeginEditNewFolder(newFolder);
@ -566,6 +609,7 @@ namespace HeBianGu.App.Disk
} }
} }
//minio创建新建文件
public async Task CreateMinIOFolder(string folderName) public async Task CreateMinIOFolder(string folderName)
{ {
var builder = new ConfigurationBuilder() var builder = new ConfigurationBuilder()
@ -618,6 +662,7 @@ namespace HeBianGu.App.Disk
} }
} }
//获取当前路径下的桶
private string GetCurrentBucket() private string GetCurrentBucket()
{ {
if (string.IsNullOrEmpty(CurrentMinIOPath)) if (string.IsNullOrEmpty(CurrentMinIOPath))
@ -626,6 +671,7 @@ namespace HeBianGu.App.Disk
return CurrentMinIOPath.Split('/')[0]; return CurrentMinIOPath.Split('/')[0];
} }
//获取桶下的文件路径
private string GetCurrentPrefix() private string GetCurrentPrefix()
{ {
if (string.IsNullOrEmpty(CurrentMinIOPath) || CurrentMinIOPath.IndexOf('/') < 0) if (string.IsNullOrEmpty(CurrentMinIOPath) || CurrentMinIOPath.IndexOf('/') < 0)