diff --git a/PetWash.Api/petwash.db b/PetWash.Api/petwash.db index 847d615..a58fbd2 100644 Binary files a/PetWash.Api/petwash.db and b/PetWash.Api/petwash.db differ diff --git a/PetWashControl/App.xaml.cs b/PetWashControl/App.xaml.cs index 385c9e8..d403f0d 100644 --- a/PetWashControl/App.xaml.cs +++ b/PetWashControl/App.xaml.cs @@ -9,6 +9,17 @@ namespace PetWashControl /// public partial class App : Application { + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + // 全局异常处理 + this.DispatcherUnhandledException += (s, args) => + { + MessageBox.Show($"应用程序错误:\n{args.Exception.Message}\n\n{args.Exception.StackTrace}", + "错误", MessageBoxButton.OK, MessageBoxImage.Error); + args.Handled = true; + }; + } } - } diff --git a/PetWashControl/Converters/BoolToStatusConverter.cs b/PetWashControl/Converters/BoolToStatusConverter.cs index d266d81..8aa814e 100644 --- a/PetWashControl/Converters/BoolToStatusConverter.cs +++ b/PetWashControl/Converters/BoolToStatusConverter.cs @@ -71,19 +71,19 @@ public class InverseBoolToVisibilityConverter : IValueConverter } } -public class ProgressToWidthConverter : IValueConverter +public class ProgressToWidthConverter : IMultiValueConverter { - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { - if (value is int progress) + if (values.Length == 2 && values[0] is int progress && values[1] is double containerWidth) { - // 假设进度条容器宽度为300,根据百分比计算实际宽度 - return progress * 3.0; // 300px * (progress/100) + // 根据进度百分比计算实际宽度 + return containerWidth * progress / 100.0; } return 0.0; } - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new NotImplementedException(); } diff --git a/PetWashControl/ViewModels/MainViewModel.cs b/PetWashControl/ViewModels/MainViewModel.cs index 63c5a0d..4275647 100644 --- a/PetWashControl/ViewModels/MainViewModel.cs +++ b/PetWashControl/ViewModels/MainViewModel.cs @@ -125,6 +125,15 @@ public partial class MainViewModel : ObservableObject [ObservableProperty] private int _uvSterilizationTime = 3; + [ObservableProperty] + private bool _isCleaningDialogOpen; + + [ObservableProperty] + private string _cleaningMessage = "正在清理笼子..."; + + [ObservableProperty] + private int _cleaningProgress; + [ObservableProperty] private int _shampoo1Level = 80; @@ -221,7 +230,7 @@ public partial class MainViewModel : ObservableObject WashSteps.Add(new WashStep { Name = "第四次冲水", Status = "等待中" }); WashSteps.Add(new WashStep { Name = "热风吹毛", Status = "等待中" }); WashSteps.Add(new WashStep { Name = "冷热风混合", Status = "等待中" }); - WashSteps.Add(new WashStep { Name = "紫外线杀菌", Status = "等待中" }); + // 紫外线杀菌不在洗护流程中,在流程完成后独立执行 } public async Task InitializeAsync() @@ -800,8 +809,8 @@ public partial class MainViewModel : ObservableObject ("护理液喷洒", SprayShampoo3Time * 60), ("第四次冲水", AfterShampoo3SprayTime * 60), ("热风吹毛", HotAirTime * 60), - ("冷热风混合", ColdAirTime * 60), - ("紫外线杀菌", UvSterilizationTime * 60) + ("冷热风混合", ColdAirTime * 60) + // 紫外线杀菌不在洗护流程中 }; int totalDuration = steps.Sum(s => s.Item2); @@ -864,8 +873,14 @@ public partial class MainViewModel : ObservableObject } }); - // 洗护完成 - await CompleteWashingAsync(); + // 洗护流程完成,自动开门 + _logger.LogInfo("洗护流程完成,自动开门"); + IsDoorOpen = true; + StatusMessage = "洗护完成,请取走宠物"; + CurrentStep = "请取走宠物"; + + // 等待门关闭(模拟宠物取走后关门) + await WaitForDoorCloseAsync(); } catch (Exception ex) { @@ -874,6 +889,83 @@ public partial class MainViewModel : ObservableObject } } + /// + /// 等待门关闭(宠物取走后) + /// + private async Task WaitForDoorCloseAsync() + { + _logger.LogInfo("等待门关闭..."); + + // 在实际生产环境中,这里应该监听门传感器信号 + // 这里模拟等待10秒后自动关门 + await Task.Delay(10000); + + IsDoorOpen = false; + _logger.LogInfo("门已关闭,开始清理和杀菌流程"); + + // 门关闭后,开始清理和杀菌流程 + await StartCleaningAndSterilizationAsync(); + } + + /// + /// 清理和紫外线杀菌流程(独立于洗护流程) + /// 关门后冲水2分钟清理笼子内多余狗毛,同时紫外线灯开启杀菌 + /// + private async Task StartCleaningAndSterilizationAsync() + { + try + { + // 显示清理弹窗(不可手动关闭) + IsCleaningDialogOpen = true; + CleaningProgress = 0; + + _logger.LogInfo("开始清理和杀菌流程"); + + // 冲水2分钟 + 紫外线杀菌时间 + int flushDuration = 2 * 60; // 2分钟冲水 + int uvDuration = UvSterilizationTime * 60; // 紫外线杀菌时间 + int totalDuration = flushDuration + uvDuration; + + // 第一阶段:冲水2分钟清理狗毛,同时开启紫外线灯 + _logger.LogInfo("开始冲水清理狗毛,同时开启紫外线灯"); + CleaningMessage = "正在冲水清理笼子..."; + + for (int i = 0; i <= flushDuration; i++) + { + CleaningProgress = (int)((double)i / totalDuration * 100); + await Task.Delay(100); + } + + // 第二阶段:继续紫外线杀菌 + _logger.LogInfo("冲水完成,继续紫外线杀菌"); + CleaningMessage = "正在紫外线杀菌..."; + + for (int i = flushDuration; i <= totalDuration; i++) + { + CleaningProgress = (int)((double)i / totalDuration * 100); + await Task.Delay(100); + } + + CleaningProgress = 100; + CleaningMessage = "清理完成!"; + await Task.Delay(1000); + + // 关闭清理弹窗 + IsCleaningDialogOpen = false; + + _logger.LogInfo("清理和杀菌流程完成"); + + // 全部完成,返回待机界面 + await CompleteWashingAsync(); + } + catch (Exception ex) + { + _logger.LogError("清理和杀菌流程失败", ex); + StatusMessage = $"清理失败: {ex.Message}"; + IsCleaningDialogOpen = false; + } + } + private async Task CompleteWashingAsync() { if (CurrentOrder == null) return; diff --git a/PetWashControl/Views/MainWindow.xaml b/PetWashControl/Views/MainWindow.xaml index 4f7d9ca..b1ca842 100644 --- a/PetWashControl/Views/MainWindow.xaml +++ b/PetWashControl/Views/MainWindow.xaml @@ -1303,11 +1303,17 @@ + Margin="0,0,0,10" + x:Name="ProgressBarContainer"> + HorizontalAlignment="Left"> + + + + + + @@ -2092,6 +2098,119 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +