FieldWorkClient/ViewModel/Send/DownViewModel.cs

312 lines
8.7 KiB
C#
Raw Normal View History

using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
2025-04-14 13:52:04 +08:00
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
2025-04-08 16:22:25 +08:00
using HeBianGu.Base.WpfBase;
using HeBianGu.Service.Mvc;
using Hopetry.Models;
using Hopetry.Provider;
using Hopetry.Services;
using Newtonsoft.Json;
namespace Hopetry.ViewModel.Send;
[ViewModel("Down")]
public class DownViewModel : MvcViewModelBase
{
private readonly MinioService _minioService;
2025-04-12 13:23:12 +08:00
public RelayCommand<MinioDownloadTask> OpenDownItemFolder { get; set; }
private readonly ConcurrentQueue<MinioDownloadTask> _taskQueue = new();
2025-04-12 15:50:38 +08:00
private SemaphoreSlim _semaphore;
private CancellationTokenSource _processingCts = new();
2025-04-12 13:23:12 +08:00
public int count { get; set; }
private readonly ReaderWriterLockSlim _lock = new();
2025-04-14 13:52:04 +08:00
private Visibility _tab0Visibility;
2025-04-12 16:24:15 +08:00
2025-04-14 13:52:04 +08:00
public Visibility Tab0Visibility
{
get => _tab0Visibility;
set
{
_tab0Visibility = value;
RaisePropertyChanged();
}
}
private Visibility _tab1Visibility;
public Visibility Tab1Visibility
{
get => _tab1Visibility;
set
{
_tab1Visibility = value;
RaisePropertyChanged();
}
}
private int _tabIndex;
public int TabIndex
{
get => _tabIndex;
set
{
_tabIndex = value;
if (_tabIndex == 0)
{
Tab0Visibility = Visibility.Visible;
Tab1Visibility = Visibility.Hidden;
}
else if (_tabIndex == 1)
{
Tab0Visibility = Visibility.Hidden;
Tab1Visibility = Visibility.Visible;
}
RaisePropertyChanged();
}
}
/// <summary>
/// 全部任务动态标题
/// </summary>
2025-04-10 14:31:05 +08:00
private string _allTaskHeader;
public string AllTaskHeader
{
2025-04-10 14:31:05 +08:00
get => _allTaskHeader;
set
{
_allTaskHeader = value;
RaisePropertyChanged();
}
}
private string _runningTaskHeader;
public string RunningTaskHeader
{
get => _runningTaskHeader;
set
{
2025-04-10 14:31:05 +08:00
_runningTaskHeader = value;
RaisePropertyChanged();
}
}
private string _finishedTaskHeader;
public string FinishedTaskHeader
{
get => _finishedTaskHeader;
set
{
_finishedTaskHeader = value;
RaisePropertyChanged();
}
}
// 绑定属性
2025-04-12 15:50:38 +08:00
public ObservableCollection<MinioDownloadTask> AllTasks { get; set; }
2025-04-12 13:23:12 +08:00
public ICollectionView RunningTasksView { get; set; }
2025-04-10 14:31:05 +08:00
public ICollectionView FinishedTasksView { get; set; }
private int _maxConcurrent = 3;
public int MaxConcurrent
{
get => _maxConcurrent;
set
{
if (value < 1) value = 1;
if (_maxConcurrent == value) return;
_maxConcurrent = value;
2025-04-12 13:23:12 +08:00
//AdjustConcurrency();
RaisePropertyChanged();
}
}
private int _runningTasks;
public int RunningTasks
{
get => _runningTasks;
private set
{
_runningTasks = value;
RaisePropertyChanged();
}
}
// 命令
2025-04-12 13:23:12 +08:00
public ICommand AddTaskCommand { get; set; }
public ICommand ClearFinishedCommand { get; }
2025-04-12 16:24:15 +08:00
private readonly ISerializerService _serializerService;
2025-04-08 16:22:25 +08:00
2025-04-10 14:31:05 +08:00
/// <summary>
/// 构造函数
/// </summary>
/// <param name="minioService"></param>
2025-04-12 16:24:15 +08:00
public DownViewModel(MinioService minioService, ISerializerService serializerService)
2025-04-08 16:22:25 +08:00
{
2025-04-12 16:24:15 +08:00
_serializerService = serializerService;
2025-04-08 16:22:25 +08:00
_minioService = minioService;
Console.WriteLine("初始化DownViewModel");
2025-04-12 13:23:12 +08:00
using var client = SqlSugarConfig.GetSqlSugarScope();
var data = client.Ado.SqlQuery<MinioDownloadTask>($"select * from download_task");
AllTasks = new ObservableCollection<MinioDownloadTask>(data);
AllTaskHeader = $"全部({AllTasks.Count}";
2025-04-12 13:23:12 +08:00
//Console.WriteLine(JsonConvert.SerializeObject(data));
OpenDownItemFolder = new RelayCommand<MinioDownloadTask>(DoOpenDownItemFolder);
var cvsRunning = new CollectionViewSource { Source = AllTasks };
cvsRunning.Filter += (s, e) =>
{
var b = ((MinioDownloadTask)e.Item).Status is "下载中" or "等待中" or "已暂停";
e.Accepted = b;
};
RunningTasksView = cvsRunning.View;
var cvsFinished = new CollectionViewSource { Source = AllTasks };
cvsFinished.Filter += (s, e) =>
{
var b = ((MinioDownloadTask)e.Item).Status == "已完成";
e.Accepted = b;
};
FinishedTasksView = cvsFinished.View;
2025-04-14 13:52:04 +08:00
if (FinishedTasksView is ListCollectionView finishListView)
{
FinishedTaskHeader = $"已完成({finishListView.Count}";
}
if (RunningTasksView is ListCollectionView runningListView)
{
RunningTaskHeader = $"下载中({runningListView.Count}";
}
2025-04-10 14:31:05 +08:00
// 关键:订阅数据源变更事件,强制视图刷新
AllTasks.CollectionChanged += (s, e) =>
{
RunningTasksView.Refresh();
2025-04-10 14:31:05 +08:00
FinishedTasksView.Refresh();
2025-04-14 13:52:04 +08:00
if (FinishedTasksView is ListCollectionView finishListView)
{
FinishedTaskHeader = $"已完成({finishListView.Count}";
}
if (RunningTasksView is ListCollectionView runningListView)
{
RunningTaskHeader = $"下载中({runningListView.Count}";
}
};
2025-04-12 13:23:12 +08:00
ClearFinishedCommand = new CustomCommand(() =>
{
// todo 删除已完成的下载记录
});
2025-04-12 13:23:12 +08:00
// 启动任务处理线程
_semaphore = new SemaphoreSlim(_maxConcurrent);
new Thread(ProcessTasksLoop) { IsBackground = true }.Start();
2025-04-12 15:50:38 +08:00
//AddTaskCommand = new ActionCommand(AddTask);
}
2025-04-12 13:23:12 +08:00
2025-04-12 15:50:38 +08:00
private async void ProcessTasksLoop()
{
2025-04-12 15:50:38 +08:00
int c1 = 1;
while (!_processingCts.IsCancellationRequested)
{
2025-04-12 15:50:38 +08:00
if (_taskQueue.TryDequeue(out var task))
{
2025-04-14 13:52:04 +08:00
Console.WriteLine("存在可下载任务,正在申请许可...");
await _semaphore.WaitAsync();
Console.WriteLine("申请下载许可成功!马上开启下载");
2025-04-12 15:50:38 +08:00
// 启动新线程执行下载任务
2025-04-12 16:24:15 +08:00
// _ = Task.Run(() => ExecuteTaskAsync(task));
_ = ExecuteTaskAsync(task).ContinueWith(_ => _semaphore.Release());
}
2025-04-14 13:52:04 +08:00
// 无任务时,进入低功耗轮询
Thread.Sleep(500);
}
}
2025-04-12 16:24:15 +08:00
public void AddTask(string bucketName, string objectKey)
{
2025-04-12 16:24:15 +08:00
var downDir = ViewModelLocator.SyncViewModel.SyncDir;
2025-04-14 13:52:04 +08:00
var task = new MinioDownloadTask(_minioService, bucketName, objectKey, downDir);
2025-04-12 13:23:12 +08:00
using var client = SqlSugarConfig.GetSqlSugarScope();
client.Insertable(task).ExecuteCommandIdentityIntoEntity();
AllTasks.Add(task);
_taskQueue.Enqueue(task);
}
private async Task ExecuteTaskAsync(MinioDownloadTask task)
{
try
{
2025-04-12 13:23:12 +08:00
await task.StartDownload();
2025-04-14 13:52:04 +08:00
var x = AllTasks.IndexOf(task);
AllTasks[AllTasks.IndexOf(task)] = task;
/*var temp = AllTasks[x];
temp.Status = "已完成";*/
//Console.WriteLine($"所有任务取出任务id {temp.TaskId} 完成任务id{task.TaskId}" );
2025-04-12 16:24:15 +08:00
Console.WriteLine($"完成任务在全部任务中的位置 {x}");
2025-04-14 13:52:04 +08:00
//RefreshViewHeader();
2025-04-12 15:50:38 +08:00
Console.WriteLine($"异步下载完成:{task.FileName}");
}
finally
{
}
}
private void AdjustConcurrency()
{
2025-04-12 15:50:38 +08:00
lock (_semaphore)
{
// 调整信号量容量
2025-04-12 15:50:38 +08:00
var delta = _maxConcurrent - _semaphore.CurrentCount;
if (delta > 0)
{
for (int i = 0; i < delta; i++)
{
2025-04-12 15:50:38 +08:00
_semaphore.Release();
}
}
}
}
2025-04-12 13:23:12 +08:00
public void DoOpenDownItemFolder(MinioDownloadTask para)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine($"点击item值{JsonConvert.SerializeObject(para)}");
Process.Start("explorer.exe", para.FilePath);
}
2025-04-12 13:23:12 +08:00
public void DoCancelDownItem(MinioDownloadTask item)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine("取消下载");
// todo 实现取消下载
}
2025-04-12 13:23:12 +08:00
public void DoPauseDownItem(MinioDownloadTask item)
{
2025-04-12 13:23:12 +08:00
Console.WriteLine("暂停下载");
// todo 实现暂停下载
2025-04-08 16:22:25 +08:00
}
protected override void Init()
{
}
protected override void Loaded(string args)
{
}
2025-04-14 13:52:04 +08:00
2025-04-08 16:22:25 +08:00
}