重构CpuType

This commit is contained in:
2025-07-27 21:58:50 +08:00
parent 8b9b096df9
commit 824c3e4df6
12 changed files with 149 additions and 33 deletions

View File

@@ -15,7 +15,7 @@ public class DeviceDto
public int Port { get; set; } public int Port { get; set; }
public int Rack { get; set; } public int Rack { get; set; }
public int Slot { get; set; } public int Slot { get; set; }
public string CpuType { get; set; } public CpuType CpuType { get; set; }
public DeviceType DeviceType { get; set; } public DeviceType DeviceType { get; set; }
public string OpcUaServerUrl { get; set; } public string OpcUaServerUrl { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }

15
DMS.Core/Enums/CpuType.cs Normal file
View File

@@ -0,0 +1,15 @@
using System.ComponentModel;
namespace DMS.Core.Enums;
public enum CpuType
{
[Description("S7-1200")]
S71200,
[Description("S7-1500")]
S71500,
[Description("S7-300")]
S7300,
[Description("S7-400")]
S7400
}

View File

@@ -63,7 +63,7 @@ public class Device
/// </summary> /// </summary>
public List<VariableTable> VariableTables { get; set; } = new(); public List<VariableTable> VariableTables { get; set; } = new();
public string CpuType { get; set; } public CpuType CpuType { get; set; }
public DeviceType DeviceType { get; set; } public DeviceType DeviceType { get; set; }
public bool IsRunning { get; set; } public bool IsRunning { get; set; }
} }

View File

@@ -25,7 +25,7 @@ namespace DMS.Infrastructure.UnitTests
dbDevice.Protocol = ProtocolType.S7; dbDevice.Protocol = ProtocolType.S7;
dbDevice.Slot = 1; dbDevice.Slot = 1;
dbDevice.Rack = 0; dbDevice.Rack = 0;
dbDevice.CpuType = "S7-1200"; dbDevice.CpuType = CpuType.S71200;
dbDevice.DeviceType = Core.Enums.DeviceType.SiemensPLC; dbDevice.DeviceType = Core.Enums.DeviceType.SiemensPLC;
return dbDevice; return dbDevice;

View File

@@ -56,8 +56,8 @@ public class DbDevice
/// <summary> /// <summary>
/// ///
/// </summary> /// </summary>
[SugarColumn(IsNullable = true)] [SugarColumn(ColumnDataType="varchar(20)",SqlParameterDbType=typeof(EnumToStringConvert))]
public string CpuType { get; set; } public CpuType CpuType { get; set; }
/// <summary> /// <summary>
/// 设备槽号 (针对PLC等设备)。 /// 设备槽号 (针对PLC等设备)。
/// </summary> /// </summary>

View File

@@ -8,6 +8,7 @@ using DateTime = System.DateTime;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using DMS.Application.Interfaces; using DMS.Application.Interfaces;
using DMS.Core.Interfaces; using DMS.Core.Interfaces;
using CpuType = DMS.Core.Enums.CpuType;
namespace DMS.Infrastructure.Services; namespace DMS.Infrastructure.Services;
@@ -378,12 +379,12 @@ public class S7BackgroundService : BackgroundService
/// <param name="cpuTypeString">CPU类型的字符串表示。</param> /// <param name="cpuTypeString">CPU类型的字符串表示。</param>
/// <returns>对应的S7.Net.CpuType枚举值。</returns> /// <returns>对应的S7.Net.CpuType枚举值。</returns>
/// <exception cref="ArgumentException">如果无法解析CPU类型字符串。</exception> /// <exception cref="ArgumentException">如果无法解析CPU类型字符串。</exception>
private S7.Net.CpuType ConvertCpuType(string cpuTypeString) private S7.Net.CpuType ConvertCpuType(CpuType cpuTypeString)
{ {
if (Enum.TryParse(cpuTypeString, true, out S7.Net.CpuType cpuType)) // if (Enum.TryParse(cpuTypeString, true, out S7.Net.CpuType cpuType))
{ // {
return cpuType; // return cpuType;
} // }
throw new ArgumentException($"无法解析CPU类型: {cpuTypeString}"); throw new ArgumentException($"无法解析CPU类型: {cpuTypeString}");
} }

View File

@@ -447,4 +447,96 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
} }
} }
} }
/// <summary>
/// 将变量表关联到对应的设备上。
/// </summary>
public void AssociateVariableTablesToDevices()
{
// 1. 创建一个字典,按 DeviceId 分组所有变量表,以便高效查找
var variableTablesGroupedByDevice = _variableTables
.GroupBy(vt => vt.DeviceId)
.ToDictionary(g => g.Key, g => g.ToList());
foreach (var device in _devices)
{
// 获取当前设备应该关联的所有变量表
List<VariableTableItemViewModel> associatedVariableTables = new List<VariableTableItemViewModel>();
if (variableTablesGroupedByDevice.TryGetValue(device.Id, out var foundTables))
{
associatedVariableTables = foundTables;
}
// 创建一个HashSet用于快速查找当前设备应有的变量表ID
var shouldHaveVariableTableIds = new HashSet<int>(associatedVariableTables.Select(vt => vt.Id));
// 2. 移除不再关联的变量表
// 从后往前遍历,避免在循环中修改集合导致索引问题
for (int i = device.VariableTables.Count - 1; i >= 0; i--)
{
var existingVariableTable = device.VariableTables[i];
if (!shouldHaveVariableTableIds.Contains(existingVariableTable.Id))
{
device.VariableTables.RemoveAt(i);
}
}
// 3. 添加新关联的变量表
var currentlyHasVariableTableIds = new HashSet<int>(device.VariableTables.Select(vt => vt.Id));
foreach (var newVariableTable in associatedVariableTables)
{
if (!currentlyHasVariableTableIds.Contains(newVariableTable.Id))
{
device.VariableTables.Add(newVariableTable);
}
// 如果已经存在,则不需要额外操作,因为 LoadVariableTables 已经更新了 _variableTables 中的实例
}
}
}
/// <summary>
/// 将变量关联到对应的变量表上。
/// </summary>
public void AssociateVariablesToVariableTables()
{
// 1. 创建一个字典,按 VariableTableId 分组所有变量,以便高效查找
var variablesGroupedByVariableTable = _variables
.GroupBy(v => v.VariableTableId)
.ToDictionary(g => g.Key, g => g.ToList());
foreach (var variableTable in _variableTables)
{
// 获取当前变量表应该关联的所有变量
List<VariableItemViewModel> associatedVariables = new List<VariableItemViewModel>();
if (variablesGroupedByVariableTable.TryGetValue(variableTable.Id, out var foundVariables))
{
associatedVariables = foundVariables;
}
// 创建一个HashSet用于快速查找当前变量表应有的变量ID
var shouldHaveVariableIds = new HashSet<int>(associatedVariables.Select(v => v.Id));
// 2. 移除不再关联的变量
// 从后往前遍历,避免在循环中修改集合导致索引问题
for (int i = variableTable.Variables.Count - 1; i >= 0; i--)
{
var existingVariable = variableTable.Variables[i];
if (!shouldHaveVariableIds.Contains(existingVariable.Id))
{
variableTable.Variables.RemoveAt(i);
}
}
// 3. 添加新关联的变量
var currentlyHasVariableIds = new HashSet<int>(variableTable.Variables.Select(v => v.Id));
foreach (var newVariable in associatedVariables)
{
if (!currentlyHasVariableIds.Contains(newVariable.Id))
{
variableTable.Variables.Add(newVariable);
}
// 如果已经存在,则不需要额外操作,因为 LoadVariables 已经更新了 _variables 中的实例
}
}
}
} }

View File

@@ -113,25 +113,25 @@ public partial class DevicesViewModel : ViewModelBase, INavigatable
PrimaryButContent = "添加设备" PrimaryButContent = "添加设备"
}; };
// 1. 显示添加设备对话框 // 1. 显示添加设备对话框
// DeviceItemViewModel device = await _dialogService.ShowDialogAsync(deviceDialogViewModel); DeviceItemViewModel device = await _dialogService.ShowDialogAsync(deviceDialogViewModel);
// // 如果用户取消或对话框未返回设备,则直接返回 // 如果用户取消或对话框未返回设备,则直接返回
// if (device == null) if (device == null)
// {
// return;
// }
DeviceItemViewModel device = new DeviceItemViewModel()
{ {
Name = "Test", return;
Description = "Test Device", }
IpAddress = "127.0.0.1",
Port = 8080,
Protocol = ProtocolType.S7,
CpuType = "S7-1200",
DeviceType = DeviceType.SiemensPLC,
IsActive = true,
}; // DeviceItemViewModel device = new DeviceItemViewModel()
// {
// Name = "Test",
// Description = "Test Device",
// IpAddress = "127.0.0.1",
// Port = 8080,
// Protocol = ProtocolType.S7,
// CpuType = "S7-1200",
// DeviceType = DeviceType.SiemensPLC,
// IsActive = true,
//
// };
CreateDeviceWithDetailsDto dto = new CreateDeviceWithDetailsDto(); CreateDeviceWithDetailsDto dto = new CreateDeviceWithDetailsDto();

View File

@@ -1,4 +1,6 @@
// 文件: DMS.WPF/ViewModels/Items/DeviceItemViewModel.cs // 文件: DMS.WPF/ViewModels/Items/DeviceItemViewModel.cs
using System.Collections.ObjectModel;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using DMS.Application.DTOs; using DMS.Application.DTOs;
using DMS.Core.Enums; using DMS.Core.Enums;
@@ -35,7 +37,7 @@ public partial class DeviceItemViewModel : ObservableObject
private int _slot; private int _slot;
[ObservableProperty] [ObservableProperty]
private string _cpuType; private CpuType _cpuType;
[ObservableProperty] [ObservableProperty]
private DeviceType _deviceType; private DeviceType _deviceType;
@@ -52,7 +54,7 @@ public partial class DeviceItemViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
private string _status; private string _status;
public List<VariableTableItemViewModel> VariableTables { get; set; } public ObservableCollection<VariableTableItemViewModel> VariableTables { get; set; } = new();
public DeviceItemViewModel(DeviceDto dto) public DeviceItemViewModel(DeviceDto dto)
{ {

View File

@@ -29,7 +29,7 @@ public partial class VariableItemViewModel : ObservableObject
private List<VariableMqttAliasDto>? _mqttAliases; private List<VariableMqttAliasDto>? _mqttAliases;
[ObservableProperty] [ObservableProperty]
private SignalType _signalType; private SignalType _signalType ;
[ObservableProperty] [ObservableProperty]
private PollLevelType _pollLevel; private PollLevelType _pollLevel;

View File

@@ -46,6 +46,10 @@ public partial class SplashViewModel : ObservableObject
await _dataServices.LoadVariableTables(); await _dataServices.LoadVariableTables();
await _dataServices.LoadVariables(); await _dataServices.LoadVariables();
await _dataServices.LoadMenus(); await _dataServices.LoadMenus();
_dataServices.AssociateVariableTablesToDevices();
_dataServices.AssociateVariablesToVariableTables();
// 可以在这里添加加载配置的逻辑 // 可以在这里添加加载配置的逻辑
await Task.Delay(500); // 模拟耗时 await Task.Delay(500); // 模拟耗时

View File

@@ -31,6 +31,8 @@
EnumType="{x:Type enums:DeviceType}" /> EnumType="{x:Type enums:DeviceType}" />
<ex:EnumBindingSource x:Key="protocolType" <ex:EnumBindingSource x:Key="protocolType"
EnumType="{x:Type enums:ProtocolType}" /> EnumType="{x:Type enums:ProtocolType}" />
<ex:EnumBindingSource x:Key="cpuType"
EnumType="{x:Type enums:CpuType}" />
<vc:EnumDescriptionConverter x:Key="EnumDescriptionConverter" /> <vc:EnumDescriptionConverter x:Key="EnumDescriptionConverter" />
@@ -125,7 +127,7 @@
HorizontalAlignment="Left" HorizontalAlignment="Left"
Style="{StaticResource TextBlockSubTitle}" /> Style="{StaticResource TextBlockSubTitle}" />
<ComboBox SelectedItem="{Binding Device.CpuType}" <ComboBox SelectedItem="{Binding Device.CpuType}"
ItemsSource="{Binding CpuTypes}" /> ItemsSource="{Binding Source={StaticResource cpuType}}" />
<!-- Rack --> <!-- Rack -->
<TextBlock Text="机架号" <TextBlock Text="机架号"