using MembranePoreTester.Communication; using MembranePoreTester.Helpers; using MembranePoreTester.Models; using Microsoft.Win32; using System.Collections.Generic; using System.Windows; using System.Windows.Input; namespace MembranePoreTester.ViewModels { public class BubblePointViewModel : ViewModelBase { private BubblePointRecord _record = new(); private TestLiquid _selectedLiquid; private bool _isCustomLiquid; private double _customSurfaceTension = 30.0; // 添加字段 private readonly IPlcService _plcService; private readonly PlcConfiguration _plcConfig; public ICommand ReadPlcCommand { get; } public BubblePointRecord Record { get => _record; set => SetProperty(ref _record, value); } public List Liquids => TestLiquid.Predefined; public List PressureUnits => new() { "Pa", "cmHg", "psi" }; public List MembraneTypes => new() { "平板膜", "中空纤维膜" }; public TestLiquid SelectedLiquid { get => _selectedLiquid; set { if (SetProperty(ref _selectedLiquid, value)) { Record.Liquid = value; OnPropertyChanged(nameof(Record.MaxPoreSize)); } } } public bool IsCustomLiquid { get => _isCustomLiquid; set { if (SetProperty(ref _isCustomLiquid, value)) { UpdateCustomLiquid(); } } } public double CustomSurfaceTension { get => _customSurfaceTension; set { if (SetProperty(ref _customSurfaceTension, value)) { UpdateCustomLiquid(); } } } private void UpdateCustomLiquid() { if (IsCustomLiquid) { Record.Liquid = new TestLiquid { Name = "自定义", SurfaceTension = CustomSurfaceTension }; OnPropertyChanged(nameof(Record.MaxPoreSize)); } } public ICommand CalculateCommand { get; } public ICommand GenerateReportCommand { get; } public ICommand OpenPressureCalibCommand { get; } public BubblePointViewModel() { _plcService = App.PlcService; _plcConfig = App.PlcConfig; CalculateCommand = new RelayCommand(Calculate); GenerateReportCommand = new RelayCommand(GenerateReport); SelectedLiquid = Liquids[0]; ReadPlcCommand = new RelayCommand(async () => await ReadPlcAsync()); SaveCommand = new RelayCommand(SaveToDatabase); ExportCommand = new RelayCommand(ExportToExcel); OpenPressureCalibCommand = new RelayCommand(OpenPressureCalibration); } private async Task ReadPlcAsync() { try { float rawPressure = await _plcService.ReadPressureAsync(StationId); Record.BubblePointPressure = rawPressure * _plcConfig.PressureFactor; OnPropertyChanged(nameof(Record.BubblePointPressure)); } catch (Exception ex) { MessageBox.Show($"读取PLC失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } } public double MaxPoreSize => Record.MaxPoreSize; private void Calculate() { // 触发最大孔径重新计算(通过绑定已自动刷新) OnPropertyChanged(nameof(Record.MaxPoreSize)); } private void GenerateReport() { ReportGenerator.GenerateBubblePointReport(Record); } public void UpdateBubblePointPressure(double pressure) { Record.BubblePointPressure = pressure; OnPropertyChanged(nameof(Record.BubblePointPressure)); OnPropertyChanged(nameof(MaxPoreSize)); // 最大孔径依赖于压力 } private int _stationId; public int StationId { get => _stationId; set => SetProperty(ref _stationId, value); } // 保存当前记录到数据库 public void SaveToDatabase() { var entity = new BubblePointEntity { StationId = StationId, TestDate = Record.TestDate, Tester = Record.Tester, SampleType = Record.SampleType, SampleSpec = Record.SampleSpec, RoomTemperature = Record.RoomTemperature, SoakingTime = Record.SoakingTime, LiquidName = Record.Liquid?.Name, LiquidSurfaceTension = Record.Liquid?.SurfaceTension ?? 0, LiquidManufacturer = Record.LiquidManufacturer, BubblePointPressure = Record.BubblePointPressure, PressureUnit = Record.PressureUnit, MaxPoreSize = Record.MaxPoreSize }; using var db = new AppDbContext(); db.BubblePointRecords.Add(entity); db.SaveChanges(); } public void LoadFromDatabase(int recordId) { using var db = new AppDbContext(); var entity = db.BubblePointRecords.Find(recordId); if (entity == null) return; Record.SampleType = entity.SampleType; Record.SampleSpec = entity.SampleSpec; Record.RoomTemperature = entity.RoomTemperature; Record.SoakingTime = entity.SoakingTime; Record.Liquid = TestLiquid.Predefined.FirstOrDefault(l => l.Name == entity.LiquidName) ?? new TestLiquid { Name = entity.LiquidName, SurfaceTension = entity.LiquidSurfaceTension }; Record.LiquidManufacturer = entity.LiquidManufacturer; Record.BubblePointPressure = entity.BubblePointPressure; Record.PressureUnit = entity.PressureUnit; Record.TestDate = entity.TestDate; Record.Tester = entity.Tester; OnPropertyChanged(nameof(Record)); OnPropertyChanged(nameof(MaxPoreSize)); // 触发界面更新 } public ICommand SaveCommand { get; } public ICommand ExportCommand { get; } private void OpenPressureCalibration() { // 使用简单的输入框获取新零点系数和量程系数 string zeroStr = Microsoft.VisualBasic.Interaction.InputBox("请输入压力零点系数", "压力校准", "0"); string spanStr = Microsoft.VisualBasic.Interaction.InputBox("请输入压力量程系数", "压力校准", "1"); if (float.TryParse(zeroStr, out float zero) && float.TryParse(spanStr, out float span)) { Task.Run(async () => { await WriteFloatAsync(_plcConfig.PressureCalibZero, zero); await WriteFloatAsync(_plcConfig.PressureCalibSpan, span); MessageBox.Show("压力校准系数已写入", "完成"); }); } } private void ExportToExcel() { var saveFileDialog = new SaveFileDialog { Filter = "Excel文件|*.xlsx", FileName = $"泡点法_工位{StationId}_{DateTime.Now:yyyyMMddHHmmss}.xlsx" }; if (saveFileDialog.ShowDialog() == true) { // 转换为Entity后导出 var entity = new BubblePointEntity { /* 从Record复制 */ }; ExportHelper.ExportBubblePoint(entity, saveFileDialog.FileName); MessageBox.Show("导出成功"); } } } }