Merge branch 'master' of http://git.51dayu.com.cn/diamond-cut/SparkClient
commit
caac05598b
11 changed files with 483 additions and 330 deletions
@ -0,0 +1,300 @@ |
||||
using System.IO; |
||||
using System.Windows.Input; |
||||
using System.Windows.Media; |
||||
using System.Windows.Media.Imaging; |
||||
using SparkClient.Model.Common; |
||||
using SparkClient.Model.Helper; |
||||
using SparkClient.Model.Services; |
||||
using SparkClient.Views.Dialog; |
||||
|
||||
namespace SparkClient.ViewModel.Grading; |
||||
|
||||
public class GradingLoadingVM : BaseViewModel,IDisposable |
||||
{ |
||||
private double _progress; |
||||
private SOCClientService _socClientService; |
||||
|
||||
/// <summary> |
||||
/// 进度 |
||||
/// </summary> |
||||
public double Progress |
||||
{ |
||||
get => _progress; |
||||
set |
||||
{ |
||||
_progress = value; |
||||
OnPropertyChanged(nameof(Progress)); |
||||
} |
||||
} |
||||
|
||||
|
||||
public ICommand StopCommand { get; } |
||||
|
||||
private string _diamondCode; |
||||
|
||||
private string _diamnondType; |
||||
|
||||
private bool _disposed; |
||||
|
||||
private CancellationTokenSource _progressCts; |
||||
private CancellationTokenSource? _playbackCts; |
||||
#region 图片播放控制 |
||||
private PlayStatus _currentStatus = PlayStatus.Stopped; |
||||
public PlayStatus CurrentStatus |
||||
{ |
||||
get => _currentStatus; |
||||
set |
||||
{ |
||||
_currentStatus = value; |
||||
OnPropertyChanged(nameof(CurrentStatus)); |
||||
OnPropertyChanged(nameof(ButtonText)); // 状态变更时更新按钮文本 |
||||
} |
||||
} |
||||
public string ButtonText => CurrentStatus switch |
||||
{ |
||||
PlayStatus.Playing => "暂停", |
||||
PlayStatus.Paused => "继续", |
||||
_ => "重播" // Stopped 状态 |
||||
}; |
||||
private CancellationTokenSource _cts; |
||||
private int _playDelay = 200; // 默认播放速度 |
||||
|
||||
public ICommand PlayControlCommand { get; } |
||||
public ICommand PreviousCommand { get; } |
||||
public ICommand NextCommand { get; } |
||||
|
||||
private int _currentIndex; |
||||
public int CurrentIndex |
||||
{ |
||||
get => _currentIndex; |
||||
set |
||||
{ |
||||
_currentIndex = value; |
||||
OnPropertyChanged(nameof(CurrentIndex)); |
||||
UpdateCurrentImage(); |
||||
} |
||||
} |
||||
|
||||
public string[] ImagePaths { get; set; } |
||||
public ImageSource CurrentImage { get; private set; } |
||||
|
||||
public bool ImageIsEnable { get; private set; } |
||||
|
||||
#endregion |
||||
|
||||
public GradingLoadingVM(string diamnondType, string diamondCode) |
||||
{ |
||||
_diamondCode = diamondCode; |
||||
_diamnondType = diamnondType; |
||||
StopCommand = new RelayCommand(Stop); |
||||
PlayControlCommand = new RelayCommand(async _ => await HandlePlayControl()); |
||||
PreviousCommand = new RelayCommand(_ => MovePrevious()); |
||||
NextCommand = new RelayCommand(_ => MoveNext()); |
||||
ImageIsEnable = false; |
||||
|
||||
_progressCts = new CancellationTokenSource(); |
||||
_playbackCts = new CancellationTokenSource(); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// 开始检测 |
||||
/// </summary> |
||||
public async Task<int> Start() |
||||
{ |
||||
//开始显示进度条 |
||||
//切工仪通讯 拉取图片 延时...5秒 |
||||
//播放图片 |
||||
//图片拉取完毕---| |
||||
// var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); |
||||
// int iProgTime = int.TryParse(configValue, out var result) ? result : 50000; |
||||
// int stepTime = iProgTime / 97; |
||||
// |
||||
// for (int i = 0; i <= 97; i++) |
||||
// { |
||||
// _progressCts.Token.ThrowIfCancellationRequested(); |
||||
// Progress = i; |
||||
// await Task.Delay(stepTime, _progressCts.Token); |
||||
// } |
||||
var progress = RunProgressAsync(_progressCts.Token); |
||||
|
||||
_socClientService = new SOCClientService(); |
||||
var processImage = _socClientService.ProcessImageCollectionAsync(); |
||||
//通知页面可以播放图片 |
||||
await processImage; |
||||
|
||||
if (!"ok".Equals(processImage.Result.Status)) |
||||
{ |
||||
_progressCts.Cancel(); |
||||
new MessageBox().Show(MultilingualHelper.getString(StatusCodes.GetConstantNameByValue(processImage.Result.Status))); |
||||
return -1; |
||||
} |
||||
|
||||
|
||||
LoadImages(processImage.Result.Images); |
||||
ImageIsEnable = true; |
||||
|
||||
await progress; |
||||
return 0; |
||||
} |
||||
|
||||
private void Stop(object param) |
||||
{ |
||||
//询问?停止:忽略 |
||||
} |
||||
|
||||
private async Task RunProgressAsync(CancellationToken token) |
||||
{ |
||||
var configValue = ConfigurationHelper.ReadConfigValue("ProgressTime"); |
||||
int totalDuration = int.TryParse(configValue, out var result) ? result : 50000; |
||||
int stepTime = totalDuration / 97; |
||||
|
||||
// 使用 IProgress 实现线程安全的进度报告 |
||||
var progress = new Progress<double>(value => |
||||
{ |
||||
if (!token.IsCancellationRequested) |
||||
Progress = value; |
||||
}); |
||||
|
||||
await Task.Run(async () => |
||||
{ |
||||
for (int i = 0; i <= 97; i++) |
||||
{ |
||||
token.ThrowIfCancellationRequested(); |
||||
|
||||
// 报告进度 |
||||
((IProgress<double>)progress).Report(i); |
||||
|
||||
// 使用可取消的延迟 |
||||
await Task.Delay(stepTime, token); |
||||
} |
||||
}, token); |
||||
} |
||||
|
||||
|
||||
public void Dispose() |
||||
{ |
||||
Dispose(true); |
||||
GC.SuppressFinalize(this); |
||||
} |
||||
|
||||
protected virtual void Dispose(bool disposing) |
||||
{ |
||||
if (_disposed) return; |
||||
|
||||
if (disposing) |
||||
{ |
||||
// 取消所有操作 |
||||
_progressCts?.Cancel(); |
||||
_playbackCts?.Cancel(); |
||||
|
||||
// 释放托管资源 |
||||
_progressCts?.Dispose(); |
||||
_playbackCts?.Dispose(); |
||||
} |
||||
|
||||
_disposed = true; |
||||
} |
||||
|
||||
#region 图片播放处理 |
||||
|
||||
public void LoadImages(string folderPath) |
||||
{ |
||||
ImagePaths = Directory.GetFiles(folderPath, "*.bmp"); |
||||
CurrentIndex = 0; |
||||
CurrentStatus = PlayStatus.Stopped; |
||||
} |
||||
public void LoadImages(List<string> folderPath) |
||||
{ |
||||
ImagePaths = folderPath.ToArray(); |
||||
CurrentIndex = 0; |
||||
CurrentStatus = PlayStatus.Stopped; |
||||
} |
||||
private async Task HandlePlayControl() |
||||
{ |
||||
switch (CurrentStatus) |
||||
{ |
||||
case PlayStatus.Stopped: |
||||
await StartPlayback(); // 开始或重播 |
||||
break; |
||||
case PlayStatus.Playing: |
||||
PausePlayback(); // 暂停 |
||||
break; |
||||
case PlayStatus.Paused: |
||||
await ResumePlayback();// 继续 |
||||
break; |
||||
} |
||||
} |
||||
private async Task StartPlayback() |
||||
{ |
||||
CurrentStatus = PlayStatus.Playing; |
||||
_cts = new CancellationTokenSource(); |
||||
|
||||
try |
||||
{ |
||||
for (CurrentIndex = 0; CurrentIndex < ImagePaths.Length; CurrentIndex++) |
||||
{ |
||||
if (_cts.Token.IsCancellationRequested) break; |
||||
await Task.Delay(_playDelay); |
||||
} |
||||
|
||||
// 播放完成处理 |
||||
if (CurrentIndex >= ImagePaths.Length) |
||||
{ |
||||
CurrentStatus = PlayStatus.Stopped; |
||||
CurrentIndex = 0; // 重置为初始位置 |
||||
} |
||||
} |
||||
catch (TaskCanceledException) { /* 正常取消处理 */ } |
||||
} |
||||
|
||||
private void PausePlayback() |
||||
{ |
||||
_cts?.Cancel(); |
||||
CurrentStatus = PlayStatus.Paused; |
||||
} |
||||
|
||||
private async Task ResumePlayback() |
||||
{ |
||||
CurrentStatus = PlayStatus.Playing; |
||||
_cts = new CancellationTokenSource(); |
||||
await StartPlayback(); |
||||
} |
||||
private void UpdateCurrentImage() |
||||
{ |
||||
if (ImagePaths == null || CurrentIndex < 0 || CurrentIndex >= ImagePaths.Length) |
||||
return; |
||||
|
||||
var bitmap = new BitmapImage(); |
||||
bitmap.BeginInit(); |
||||
bitmap.CacheOption = BitmapCacheOption.OnLoad; |
||||
bitmap.UriSource = new Uri(ImagePaths[CurrentIndex]); |
||||
bitmap.EndInit(); |
||||
bitmap.Freeze(); // 确保跨线程安全 |
||||
|
||||
CurrentImage = bitmap; |
||||
OnPropertyChanged(nameof(CurrentImage)); |
||||
} |
||||
|
||||
private void MovePrevious() |
||||
{ |
||||
if (CurrentStatus == PlayStatus.Playing) |
||||
PausePlayback(); |
||||
|
||||
CurrentIndex = (CurrentIndex - 1 + ImagePaths.Length) % ImagePaths.Length; |
||||
} |
||||
|
||||
private void MoveNext() |
||||
{ |
||||
if (CurrentStatus == PlayStatus.Playing) |
||||
PausePlayback(); |
||||
|
||||
CurrentIndex = (CurrentIndex + 1) % ImagePaths.Length; |
||||
} |
||||
#endregion |
||||
} |
||||
public enum PlayStatus |
||||
{ |
||||
Stopped, // 初始/停止状态 |
||||
Playing, // 播放中 |
||||
Paused // 暂停中 |
||||
} |
Loading…
Reference in new issue