DamagesPage.xaml.cs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. using Panuon.WPF.UI;
  2. using SWRIS.Core;
  3. using SWRIS.Dtos;
  4. using SWRIS.Extensions;
  5. using SWRIS.Models;
  6. using SWRIS.Models.ViewModel;
  7. using SWRIS.Repository;
  8. using System;
  9. using System.Collections.ObjectModel;
  10. using System.Linq;
  11. using System.Windows;
  12. using System.Windows.Controls;
  13. using System.Windows.Controls.Primitives;
  14. using System.Windows.Input;
  15. namespace SWRIS.Pages
  16. {
  17. /// <summary>
  18. /// DamagesPage.xaml 的交互逻辑
  19. /// </summary>
  20. public partial class DamagesPage : Page
  21. {
  22. private readonly string[] _colors = new string[] { "#70a1d7", "#a1de93", "#f7f48b", "#f47c7c", "#c264fe", "#00fff5", "#f8b195", "#7a08fa" };
  23. private readonly IRecordRepository recordRepository;
  24. public DamagesViewModel DamagesView { get; set; }
  25. public DamagesPage()
  26. {
  27. InitializeComponent();
  28. DamagesView = new DamagesViewModel
  29. {
  30. Record = new RecordDto(),
  31. Sensors = new ObservableCollection<SensorModel>()
  32. };
  33. recordRepository = new RecordRepository();
  34. }
  35. private void Page_Loaded(object sender, RoutedEventArgs e)
  36. {
  37. if (NavigationService != null)
  38. {
  39. var query = System.Web.HttpUtility.ParseQueryString(NavigationService.CurrentSource.OriginalString.Split('?')[1]);
  40. var record = recordRepository.GetRecord(int.Parse(query["id"]));
  41. if (record != null && record.DataFilePath != null)
  42. {
  43. DamagesView.Record = record;
  44. var inUseSensors = record.InUseSensors?.Split(',').Select(s => int.Parse(s.Trim())).ToArray();
  45. foreach (var sensorNo in inUseSensors)
  46. {
  47. var sensor = new SensorModel
  48. {
  49. Id = sensorNo,
  50. Name = $"传感器{sensorNo}",
  51. Color = _colors[sensorNo - 1],
  52. IsActive = false
  53. };
  54. sensor.PropertyChanged += (s, arg) =>
  55. {
  56. if (arg.PropertyName == nameof(SensorModel.IsActive))
  57. {
  58. if (s is SensorModel sensor1 && sensor1 != null && sensor1.IsActive)
  59. {
  60. // 标记由传感器联动取消合值,避免触发"取消合值自动选中所有传感器"
  61. DamagesView.IsSensorSyncing = true;
  62. // 如果有传感器被选中,取消合值的选中状态
  63. DamagesView.IsSummaryActive = false;
  64. DamagesView.IsSensorSyncing = false;
  65. }
  66. }
  67. };
  68. DamagesView.Sensors.Add(sensor);
  69. }
  70. var damageData = DatFileHandler.ReadDatFile(record.DataFilePath);
  71. if (damageData?.Length > 0)
  72. {
  73. var parsedData = ParseSensorData(damageData, record.SensorCount, record.StartPoint, record.EndPoint);
  74. chartLine.AddDataPoints(parsedData, inUseSensors, record.Damages.ToList());
  75. }
  76. }
  77. }
  78. DataContext = DamagesView;
  79. }
  80. private void Delete_MouseDown(object sender, MouseButtonEventArgs e)
  81. {
  82. if ((sender as Image)?.Tag is int id)
  83. {
  84. var result = MessageBoxX.Show(Application.Current.MainWindow, "此操作不可恢复,是否确认删除损伤记录?", "警告", MessageBoxButton.YesNo, MessageBoxIcon.Warning, DefaultButton.YesOK);
  85. if (result == MessageBoxResult.Yes)
  86. {
  87. if (recordRepository.DeleteDamage(id))
  88. {
  89. DamagesView.Record.Damages.Remove(DamagesView.Record.Damages.FirstOrDefault(d => d.Id == id));
  90. recordRepository.UpdateRecordDamageCount(DamagesView.Record.Id.Value, DamagesView.Record.Damages.Count());
  91. NoticeBox.Show("损伤数据删除成功", "通知", MessageBoxIcon.Success, false, 3000);
  92. }
  93. }
  94. }
  95. }
  96. private void GoBack_Click(object sender, RoutedEventArgs e)
  97. {
  98. NavigationService?.GoBack();
  99. }
  100. public (double[] Positions, ushort[,] Damages) ParseSensorData(byte[] data, int sensorCount, double startPosition, double endPosition)
  101. {
  102. // 起止位置差值的绝对值过小时,采样步长趋近于0,位置轴退化,直接返回
  103. if (Math.Abs(endPosition - startPosition) < 0.001)
  104. {
  105. LogHelper.Error($"起止位置差值过小({Math.Abs(endPosition - startPosition)}),跳过数据解析。");
  106. return (null, null);
  107. }
  108. // 检查数据长度是否能被传感器数量整除
  109. if (data.Length % sensorCount != 0)
  110. {
  111. LogHelper.Error($"数据长度不匹配。数据长度 {data.Length} 字节不能被传感器数量 {sensorCount} 整除。");
  112. return (null, null);
  113. }
  114. // 计算样本数量
  115. int sampleCount = data.Length / sensorCount;
  116. // 计算采样步长
  117. double samplingStep = (endPosition - startPosition) / (sampleCount - 1);
  118. // 初始化结果列表
  119. (double[] Positions, ushort[,] Damages) sensorData = (new double[sampleCount], new ushort[sensorCount, sampleCount]);
  120. // 解析数据
  121. for (int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++)
  122. {
  123. sensorData.Positions[sampleIndex] = startPosition;
  124. for (int sensorIndex = 0; sensorIndex < sensorCount; sensorIndex++)
  125. {
  126. // 计算数据在字节数组中的位置
  127. int dataIndex = (sampleIndex * sensorCount) + sensorIndex;
  128. // 将 byte 转换为 ushort(直接赋值,因为 byte 可以隐式转换为 ushort)
  129. sensorData.Damages[sensorIndex, sampleIndex] = data[dataIndex];
  130. }
  131. startPosition += samplingStep;
  132. }
  133. return sensorData;
  134. }
  135. private void Sensor_Checked(object sender, RoutedEventArgs e)
  136. {
  137. if (sender is ToggleButton toggleButton && int.TryParse(toggleButton.Tag?.ToString(), out int id))
  138. {
  139. chartLine?.SignalPlotVisible(id, true);
  140. }
  141. }
  142. private void Sensor_UnChecked(object sender, RoutedEventArgs e)
  143. {
  144. if (sender is ToggleButton toggleButton && int.TryParse(toggleButton.Tag?.ToString(), out int id))
  145. {
  146. chartLine?.SignalPlotVisible(id, false);
  147. }
  148. }
  149. }
  150. }