From 49f1cc0cf7dea4b349ecdd9f40ac916c21fc88e6 Mon Sep 17 00:00:00 2001 From: "GukSang.Jin" Date: Wed, 20 May 2026 15:44:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ViewModels/StationViewModel.cs | 52 +++++++++++++++++++++++++++++++--- Views/MainWindow.xaml | 1 + 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/ViewModels/StationViewModel.cs b/ViewModels/StationViewModel.cs index a2e7e11..87af4eb 100644 --- a/ViewModels/StationViewModel.cs +++ b/ViewModels/StationViewModel.cs @@ -151,10 +151,12 @@ namespace TabletTester2025.ViewModels [ObservableProperty] private double _friabilityCurrentRpm; [ObservableProperty] private double _friabilityRealtimeRounds; [ObservableProperty] private int _friabilityRemainingRounds = 100; + [ObservableProperty] private bool _canSaveFriabilityResult; public IAsyncRelayCommand StopHardnessCommand { get; } public IAsyncRelayCommand StopFriabilityCommand { get; } public IAsyncRelayCommand ResetFriabilityCommand { get; } public IAsyncRelayCommand PrintFriabilityCommand { get; } + public IAsyncRelayCommand SaveFriabilityResultCommand { get; } // 溶出度新增 [ObservableProperty] private double _dissolutionUpDownFreq = 32; @@ -222,6 +224,7 @@ namespace TabletTester2025.ViewModels StartHardnessCommand = new AsyncRelayCommand(RunHardnessAsync); StartFriabilityCommand = new AsyncRelayCommand(RunFriabilityAsync); + SaveFriabilityResultCommand = new AsyncRelayCommand(SaveFriabilityResultAsync); StartDisintegrationCommand = new AsyncRelayCommand(RunDisintegrationAsync); ClearHardnessRecordsCommand = new AsyncRelayCommand(ClearHardnessRecordsAsync); @@ -310,11 +313,13 @@ namespace TabletTester2025.ViewModels if (_plcConfig.FriabilityStartCoilStop != 0) await PulseCoilAsync(_plcConfig.FriabilityStartCoilStop); _isFriabilityRunning = false; + CanSaveFriabilityResult = false; RefreshOverallPhase(); }); ResetFriabilityCommand = new AsyncRelayCommand(() => { FriabilityRemainingRounds = FriabilityTargetRounds; + CanSaveFriabilityResult = false; LossPercent = 0; // 失重率清零 SetFriabilityWeightFromPlc(0, 0); // 清空界面结果,不向PLC写零 return Task.CompletedTask; @@ -1797,7 +1802,6 @@ namespace TabletTester2025.ViewModels HardnessAvg = stats.Average; HardnessAverageDeviation = stats.AverageDeviation; HardnessRSD = stats.RsdPercent; - HardnessMax = stats.Maximum; HardnessMin = stats.Minimum; HardnessCurrentCount = stats.Count; HardnessPass = stats.IsPass; @@ -1848,6 +1852,7 @@ namespace TabletTester2025.ViewModels // 2. 标记当前正在运行的是脆碎度测试 CurrentTest = TestType.Friability; _isFriabilityRunning = true; + CanSaveFriabilityResult = false; RefreshOverallPhase(); FriabilityPass = false; bool resultReady = false; @@ -1935,12 +1940,45 @@ namespace TabletTester2025.ViewModels _isFriabilityRunning = false; RefreshOverallPhase(); - FriabilityRemainingRounds = FriabilityTargetRounds; if (resultReady) - await SaveBatchResult(TestType.Friability); + { + CanSaveFriabilityResult = true; + FriabilityRemainingRounds = 0; + } + else + { + CanSaveFriabilityResult = false; + FriabilityRemainingRounds = FriabilityTargetRounds; + } } } + private async Task SaveFriabilityResultAsync() + { + if (!CanSaveFriabilityResult) + return; + + if (!TryCalculateFriabilityLossFromWeights(out double localLossPercent)) + { + bool plcLossReady = await TryRefreshFriabilityLossPercentFromPlcAsync(); + if (!plcLossReady) + { + await App.Current.Dispatcher.InvokeAsync(() => + MessageBox.Show("脆碎度实际数据异常,请确认前重、后重和失重率。", "保存失败", MessageBoxButton.OK, MessageBoxImage.Warning)); + return; + } + } + else + { + LossPercent = localLossPercent; + FriabilityPass = LossPercent <= FriabilityMaxLossPercent; + } + + bool saved = await SaveBatchResult(TestType.Friability); + if (saved) + CanSaveFriabilityResult = false; + } + private async Task ReadFriabilityWeightAsync(ushort registerAddress, string label) { if (registerAddress == 0) @@ -2333,6 +2371,12 @@ namespace TabletTester2025.ViewModels string effectiveDissolutionChannel = testType == TestType.Dissolution ? dissolutionChannel : ""; + double batchHardnessMax = testType == TestType.Hardness + ? _hardnessResults + .Where(value => double.IsFinite(value) && value > 0) + .DefaultIfEmpty(HardnessMax) + .Max() + : HardnessMax; var batch = new TestBatch { @@ -2344,7 +2388,7 @@ namespace TabletTester2025.ViewModels HardnessAvg = HardnessAvg, HardnessAverageDeviation = HardnessAverageDeviation, HardnessRSD = HardnessRSD, - HardnessMax = HardnessMax, + HardnessMax = batchHardnessMax, HardnessMin = HardnessMin, HardnessTestCount = HardnessTestCount, HardnessInternalMin = HardnessInternalMin, diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml index cc27315..7c9c61c 100644 --- a/Views/MainWindow.xaml +++ b/Views/MainWindow.xaml @@ -531,6 +531,7 @@