Merge remote-tracking branch 'origin/dev' into dev

dev
陈伟 2025-03-24 10:24:42 +08:00
commit 532beae7b6
4 changed files with 180 additions and 60 deletions

View File

@ -18,8 +18,8 @@
Height="15" Height="15"
CornerRadius="2" CornerRadius="2"
Maximum="100" Maximum="100"
Value="{Binding Progress}"> Value="{Binding Progress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<h:FProgressBar.Triggers> <!--<h:FProgressBar.Triggers>
<EventTrigger RoutedEvent="Loaded"> <EventTrigger RoutedEvent="Loaded">
<BeginStoryboard> <BeginStoryboard>
<Storyboard Timeline.DesiredFrameRate="{x:Static h:StoryboardSetting.DesiredFrameRate}"> <Storyboard Timeline.DesiredFrameRate="{x:Static h:StoryboardSetting.DesiredFrameRate}">
@ -30,9 +30,9 @@
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</EventTrigger> </EventTrigger>
</h:FProgressBar.Triggers> </h:FProgressBar.Triggers>-->
</h:FProgressBar> </h:FProgressBar>
<TextBlock Grid.Column="7" Style="{DynamicResource {x:Static h:TextBlockKeys.Default}}" Text="184 KB/s" /> <!--<TextBlock Grid.Column="7" Style="{DynamicResource {x:Static h:TextBlockKeys.Default}}" Text="184 KB/s" />-->
<Button Grid.Column="8" <Button Grid.Column="8"
Margin="10,0" Margin="10,0"
Content="全部暂停" Content="全部暂停"
@ -40,7 +40,7 @@
<Button Grid.Column="9" Content="全部取消" Style="{DynamicResource {x:Static h:ButtonKeys.BorderBrushTransparent}}" /> <Button Grid.Column="9" Content="全部取消" Style="{DynamicResource {x:Static h:ButtonKeys.BorderBrushTransparent}}" />
</h:Row> </h:Row>
<!--<Grid Height="60" DockPanel.Dock="Top" TextBlock.Foreground="{DynamicResource {x:Static h:BrushKeys.Orange}}"> <Grid Height="60" DockPanel.Dock="Top" TextBlock.Foreground="{DynamicResource {x:Static h:BrushKeys.Orange}}">
<Border Background="{DynamicResource {x:Static h:BrushKeys.Orange}}" Opacity="0.2" /> <Border Background="{DynamicResource {x:Static h:BrushKeys.Orange}}" Opacity="0.2" />
@ -65,11 +65,12 @@
Content="免费试用" Content="免费试用"
Foreground="{DynamicResource {x:Static h:BrushKeys.ForegroundWhite}}" Foreground="{DynamicResource {x:Static h:BrushKeys.ForegroundWhite}}"
Style="{DynamicResource {x:Static h:ButtonKeys.Transparent}}" /> Style="{DynamicResource {x:Static h:ButtonKeys.Transparent}}" />
</Grid>--> </Grid>
<!--<ListBox h:Cattach.ItemHeight="Auto" Style="{DynamicResource {x:Static h:ListBoxKeys.Single}}"> <ListBox h:Cattach.ItemHeight="Auto" Style="{DynamicResource {x:Static h:ListBoxKeys.Single}}"
ItemsSource="{Binding UpLoadItems}">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type h:TestViewModel}"> <DataTemplate >
<Grid Height="50" Margin="10"> <Grid Height="50" Margin="10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
@ -124,7 +125,7 @@
<DoubleAnimation Storyboard.TargetProperty="Value" <DoubleAnimation Storyboard.TargetProperty="Value"
From="0" From="0"
To="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Value}" To="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Value}"
Duration="00:00:30" /> Duration="00:00:01" />
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</EventTrigger> </EventTrigger>
@ -156,32 +157,7 @@
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
<h:TestViewModel Int1="22" </ListBox>
Value1="701KB/21.52MB"
Value2="10:20:57"
Value3="184KB/s"
Value="FFmpeg直播推流拉流.rar" />
<h:TestViewModel Int1="45"
Value1="701KB/11.52MB"
Value2="00:20:57"
Value3="184KB/s"
Value="WPF-ControlBase-master (1).zip" />
<h:TestViewModel Int1="78"
Value1="101KB/1.53MB"
Value2="20:20:57"
Value3="284KB/s"
Value="Git-2.12.2.2-64-bit.exe" />
<h:TestViewModel Int1="11"
Value1="101KB/1.72MB"
Value2="00:40:57"
Value3="124KB/s"
Value="代码段201911271359.rar" />
<h:TestViewModel Int1="100"
Value1="2.34MB/2.34MB"
Value2=""
Value3="已完成"
Value="WPF-Chart-master.zip" />
</ListBox>-->
</DockPanel> </DockPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -11,6 +11,9 @@ using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using Minio; using Minio;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Hopetry.ViewModel.Send;
using System.IO;
using System.Security.AccessControl;
namespace HeBianGu.App.Disk namespace HeBianGu.App.Disk
{ {
@ -97,13 +100,14 @@ namespace HeBianGu.App.Disk
public LoyoutViewModel(SendViewModel sendViewModel, IConfiguration _config) public LoyoutViewModel(SendViewModel sendViewModel, IConfiguration _config)
{ {
_sendViewModel = sendViewModel; _sendViewModel = sendViewModel;
config=_config; config = _config;
UploadCommand = new AsyncRelayCommand(async () => await UploadFile()); UploadCommand = new AsyncRelayCommand(async () => await UploadFile());
} }
private SemaphoreSlim _semaphore = new SemaphoreSlim(5);
private async Task UploadFile() private async Task UploadFile()
{ {
_sendViewModel.UpLoadItems.Clear();
var openFileDialog = new Microsoft.Win32.OpenFileDialog(); var openFileDialog = new Microsoft.Win32.OpenFileDialog();
openFileDialog.Multiselect = true; // 可选择多个文件 openFileDialog.Multiselect = true; // 可选择多个文件
@ -114,23 +118,98 @@ namespace HeBianGu.App.Disk
{ {
foreach (string filePath in openFileDialog.FileNames) foreach (string filePath in openFileDialog.FileNames)
{ {
// 处理选择的文件 UpLoadItems ut = new UpLoadItems();
UploadFileToMinIOWithProgress(filePath); ut.Value = System.IO.Path.GetFileName(filePath);
ut.Value3 = "等待上传";
ut.Value5 = filePath;
FileInfo fileInfo = new FileInfo(filePath);
ut.Double1 = fileInfo.Length;
ut.Double2 = 0.0;
if (fileInfo.Exists)
{
if (fileInfo.Length < 1024 * 1024)
{
ut.Value1 = "0KB/" + Math.Round((double)(fileInfo.Length / 1024), 2).ToString() + "KB";
} }
else
{
ut.Value1 = "0MB/" + Math.Round((double)(fileInfo.Length / (1024 * 1024)), 2).ToString() + "MB";
}
}
_sendViewModel.UpLoadItems.Add(ut);
}
//更新总进度
var timer = new System.Timers.Timer(1000); // 每秒更新一次
timer.Elapsed += (sender, e) =>
{
double currentBytes = _sendViewModel.UpLoadItems.Sum(r=>r.Double2);
double totalBytes = _sendViewModel.UpLoadItems.Sum(r => r.Double1);
double speed = Math.Round((currentBytes / totalBytes)*100,0); // KB/s
_sendViewModel.Progress = speed;
};
timer.Start();
try
{
// 创建所有上传任务
var uploadTasks = _sendViewModel.UpLoadItems
.Select(async item =>
{
await _semaphore.WaitAsync(); // 等待信号量
try
{
await UploadFileToMinIOWithProgress(item);
}
finally
{
_semaphore.Release(); // 释放信号量
}
})
.ToList();
// 等待所有上传任务完成
await Task.WhenAll(uploadTasks);
//// 创建所有上传任务
//var uploadTasks = _sendViewModel.UpLoadItems
// .Select(item => UploadFileToMinIOWithProgress(item))
// .ToList();
//// 等待所有上传任务完成
//await Task.WhenAll(uploadTasks);
}
finally
{
_sendViewModel.Progress = 100;
// 停止计时器
timer.Stop();
}
//for (int i = 0; i < _sendViewModel.UpLoadItems.Count; i++)
//{
// UploadFileToMinIOWithProgress(_sendViewModel.UpLoadItems[i]);
//}
//timer.Stop();
} }
} }
private async void UploadFileToMinIOWithProgress(string filePath) private async Task UploadFileToMinIOWithProgress(UpLoadItems ut)
{ {
var minioConfig = config.GetSection("Minio"); //var minioConfig = config.GetSection("Minio");
IMinioClient client = new MinioClient() //IMinioClient client = new MinioClient()
.WithEndpoint(minioConfig["Endpoint"]) // .WithEndpoint(minioConfig["Endpoint"])
.WithCredentials(minioConfig["AccessKey"], minioConfig["SecretKey"]); // .WithCredentials(minioConfig["AccessKey"], minioConfig["SecretKey"]);
// 配置 MinIO 客户端
IMinioClient client = new Minio.MinioClient()
.WithEndpoint("123.132.248.154:9107") // MinIO 服务器地址
.WithCredentials("KcJPKzOsKfVq20EA4Lyh", "HY7K5EkYpRUphEdINZmAq34tsZD3PMLFTnL85y4N") // 访问密钥和密钥
.Build();
try try
{ {
string bucketName = "test"; string bucketName = "test";
string objectName = System.IO.Path.GetFileName(filePath); string objectName = System.IO.Path.GetFileName(ut.Value5);
//var aa = _sendViewModel.UpLoadItems.Where(r => r.Value == objectName).FirstOrDefault();
//判断桶是否存在 //判断桶是否存在
var beArgs = new BucketExistsArgs().WithBucket(bucketName); var beArgs = new BucketExistsArgs().WithBucket(bucketName);
bool found = await client.BucketExistsAsync(beArgs).ConfigureAwait(false); bool found = await client.BucketExistsAsync(beArgs).ConfigureAwait(false);
@ -143,19 +222,37 @@ namespace HeBianGu.App.Disk
var progress = new Progress<ProgressReport>(progressReport => var progress = new Progress<ProgressReport>(progressReport =>
{ {
_sendViewModel.Progress = progressReport.Percentage;// 更新进度条的值 //_sendViewModel.Progress = progressReport.Percentage;// 更新进度条的值
// 确保在 UI 线程上更新 Progress
Application.Current.Dispatcher.Invoke(() =>
{
//_sendViewModel.Progress = progressReport.Percentage;
ut.Int1 = progressReport.Percentage;
int slashIndex = ut.Value1.IndexOf('/');
long trans = progressReport.TotalBytesTransferred;
ut.Double2 = trans;
if (trans < 1024 * 1024)
{
ut.Value1 = Math.Round((double)(trans / 1024), 0).ToString() + "KB" + ut.Value1.Substring(slashIndex);
}
else
{
ut.Value1 = Math.Round((double)(trans / (1024 * 1024)), 2).ToString() + "MB" + ut.Value1.Substring(slashIndex);
}
ut.Value3 = "上传中...";
});
}); });
PutObjectArgs putObjectArgs = new PutObjectArgs() PutObjectArgs putObjectArgs = new PutObjectArgs()
.WithBucket(bucketName) .WithBucket(bucketName)
.WithObject(objectName) .WithObject(objectName)
.WithFileName(filePath) .WithFileName(ut.Value5)
//.WithContentType("application/octet-stream") //.WithContentType("application/octet-stream")
.WithProgress(progress); .WithProgress(progress);
// 上传文件并提供进度反馈 // 上传文件并提供进度反馈
await client.PutObjectAsync(putObjectArgs); await client.PutObjectAsync(putObjectArgs);
MessageBox.Show("文件上传成功!"); ut.Value3 = "已完成";
//MessageBox.Show("文件上传成功!");
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -1,4 +1,5 @@
using HeBianGu.Service.Mvc; using HeBianGu.Service.Mvc;
using Hopetry.ViewModel.Send;
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
@ -22,6 +23,9 @@ namespace HeBianGu.App.Disk
{ {
SelectLink = LinkActions[0]; SelectLink = LinkActions[0];
})); }));
} }
protected override void Loaded(string args) protected override void Loaded(string args)
@ -29,6 +33,19 @@ namespace HeBianGu.App.Disk
} }
#region 文件上传 #region 文件上传
private ObservableCollection<UpLoadItems> _upLoadItems = new ObservableCollection<UpLoadItems>();
/// <summary> 说明 </summary>
public ObservableCollection<UpLoadItems> UpLoadItems
{
get { return _upLoadItems; }
set
{
_upLoadItems = value;
RaisePropertyChanged("UpLoadItems");
}
}
private double _progress; private double _progress;
public double Progress public double Progress
@ -39,11 +56,10 @@ namespace HeBianGu.App.Disk
if (_progress != value) if (_progress != value)
{ {
_progress = value; _progress = value;
OnPropertyChanged(nameof(Progress)); RaisePropertyChanged("Progress");
} }
} }
} }
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName) protected void OnPropertyChanged(string propertyName)

View File

@ -0,0 +1,31 @@
using HeBianGu.Base.WpfBase;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Hopetry.ViewModel.Send
{
internal class UpLoadItems:TestViewModel
{
#region - 属性 -
private ObservableCollection<TreeNodeBase<TestViewModel>> _items = new ObservableCollection<TreeNodeBase<TestViewModel>>();
/// <summary> 说明 </summary>
public ObservableCollection<TreeNodeBase<TestViewModel>> Items
{
get { return _items; }
set
{
_items = value;
RaisePropertyChanged("Items");
}
}
#endregion
#region - 命令 -
#endregion
}
}