实现MQTT关联变量的别名问题,实现了,同个变量发给不同的MQTT服务器的名称不同

This commit is contained in:
2025-07-17 17:27:16 +08:00
parent 9cffb57b58
commit aea7a21d57
9 changed files with 416 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
using System;
using SqlSugar;
namespace PMSWPF.Data.Entities;
/// <summary>
/// 表示变量数据与MQTT服务器之间的关联实体包含MQTT别名。
/// </summary>
[SugarTable("VariableMqtt")]
public class DbVariableMqtt
{
/// <summary>
/// 关联的唯一标识符。
/// </summary>
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
public int Id { get; set; }
/// <summary>
/// 关联的变量数据ID。
/// </summary>
public int VariableDataId { get; set; }
/// <summary>
/// 关联的MQTT服务器ID。
/// </summary>
public int MqttId { get; set; }
/// <summary>
/// 变量在该MQTT服务器上的别名。
/// </summary>
public string MqttAlias { get; set; } = string.Empty;
/// <summary>
/// 创建时间。
/// </summary>
public DateTime CreateTime { get; set; } = DateTime.Now;
/// <summary>
/// 更新时间。
/// </summary>
public DateTime UpdateTime { get; set; } = DateTime.Now;
/// <summary>
/// 导航属性:关联的变量数据。
/// </summary>
[Navigate(NavigateType.ManyToOne, nameof(VariableDataId))]
public DbVariableData? VariableData { get; set; }
/// <summary>
/// 导航属性关联的MQTT服务器。
/// </summary>
[Navigate(NavigateType.ManyToOne, nameof(MqttId))]
public DbMqtt? Mqtt { get; set; }
}

View File

@@ -0,0 +1,123 @@
using PMSWPF.Data.Entities;
using SqlSugar;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace PMSWPF.Data.Repositories;
/// <summary>
/// 变量与MQTT服务器别名关联的数据仓库。
/// </summary>
public class VariableMqttAliasRepository
{
/// <summary>
/// 根据变量ID和MQTT服务器ID获取别名。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <returns>DbVariableMqtt实体如果不存在则为null。</returns>
public async Task<DbVariableMqtt?> GetAliasByVariableAndMqtt(int variableDataId, int mqttId)
{
using (var db = DbContext.GetInstance())
{
return await GetAliasByVariableAndMqtt(variableDataId, mqttId, db);
}
}
/// <summary>
/// 根据变量ID和MQTT服务器ID获取别名。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <param name="db">SqlSugarClient实例。</param>
/// <returns>DbVariableMqtt实体如果不存在则为null。</returns>
public async Task<DbVariableMqtt?> GetAliasByVariableAndMqtt(int variableDataId, int mqttId, SqlSugarClient db)
{
return await db.Queryable<DbVariableMqtt>()
.Where(it => it.VariableDataId == variableDataId && it.MqttId == mqttId)
.FirstAsync();
}
/// <summary>
/// 批量添加变量与MQTT服务器的关联。
/// </summary>
/// <param name="entities">要添加的DbVariableMqtt实体列表。</param>
/// <returns>成功添加的数量。</returns>
public async Task<int> AddManyAsync(IEnumerable<DbVariableMqtt> entities)
{
using (var db = DbContext.GetInstance())
{
return await AddManyAsync(entities, db);
}
}
/// <summary>
/// 批量添加变量与MQTT服务器的关联。
/// </summary>
/// <param name="entities">要添加的DbVariableMqtt实体列表。</param>
/// <param name="db">SqlSugarClient实例。</param>
/// <returns>成功添加的数量。</returns>
public async Task<int> AddManyAsync(IEnumerable<DbVariableMqtt> entities, SqlSugarClient db)
{
return await db.Insertable<DbVariableMqtt>(entities).ExecuteCommandAsync();
}
/// <summary>
/// 更新变量与MQTT服务器的别名。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <param name="newAlias">新的别名。</param>
/// <returns>受影响的行数。</returns>
public async Task<int> UpdateAliasAsync(int variableDataId, int mqttId, string newAlias)
{
using (var db = DbContext.GetInstance())
{
return await UpdateAliasAsync(variableDataId, mqttId, newAlias, db);
}
}
/// <summary>
/// 更新变量与MQTT服务器的别名。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <param name="newAlias">新的别名。</param>
/// <param name="db">SqlSugarClient实例。</param>
/// <returns>受影响的行数。</returns>
public async Task<int> UpdateAliasAsync(int variableDataId, int mqttId, string newAlias, SqlSugarClient db)
{
return await db.Updateable<DbVariableMqtt>()
.SetColumns(it => it.MqttAlias == newAlias)
.Where(it => it.VariableDataId == variableDataId && it.MqttId == mqttId)
.ExecuteCommandAsync();
}
/// <summary>
/// 删除变量与MQTT服务器的关联。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <returns>受影响的行数。</returns>
public async Task<int> DeleteAsync(int variableDataId, int mqttId)
{
using (var db = DbContext.GetInstance())
{
return await DeleteAsync(variableDataId, mqttId, db);
}
}
/// <summary>
/// 删除变量与MQTT服务器的关联。
/// </summary>
/// <param name="variableDataId">变量数据ID。</param>
/// <param name="mqttId">MQTT服务器ID。</param>
/// <param name="db">SqlSugarClient实例。</param>
/// <returns>受影响的行数。</returns>
public async Task<int> DeleteAsync(int variableDataId, int mqttId, SqlSugarClient db)
{
return await db.Deleteable<DbVariableMqtt>()
.Where(it => it.VariableDataId == variableDataId && it.MqttId == mqttId)
.ExecuteCommandAsync();
}
}

84
Models/VariableMqtt.cs Normal file
View File

@@ -0,0 +1,84 @@
using System;
using CommunityToolkit.Mvvm.ComponentModel;
using PMSWPF.Data.Entities;
using PMSWPF.Enums;
namespace PMSWPF.Models;
/// <summary>
/// 表示变量数据与MQTT服务器之间的关联模型包含MQTT别名。
/// </summary>
public partial class VariableMqtt : ObservableObject
{
public VariableMqtt()
{
}
public VariableMqtt(VariableData? variableData, Mqtt? mqtt)
{
VariableData = variableData;
Mqtt = mqtt;
MqttAlias = MqttAlias != String.Empty ? MqttAlias : variableData.Name;
}
/// <summary>
/// 关联的唯一标识符。
/// </summary>
public int Id { get; set; }
/// <summary>
/// 关联的变量数据ID。
/// </summary>
public int VariableDataId { get; set; }
/// <summary>
/// 关联的MQTT服务器ID。
/// </summary>
public int MqttId { get; set; }
/// <summary>
/// 变量在该MQTT服务器上的别名。
/// </summary>
[ObservableProperty]
private string _mqttAlias = string.Empty;
/// <summary>
/// 变量的唯一标识符S7地址或OPC UA NodeId
/// </summary>
public string Identifier
{
get
{
if (VariableData.ProtocolType == ProtocolType.S7)
{
return VariableData.S7Address;
}
else if (VariableData.ProtocolType == ProtocolType.OpcUA)
{
return VariableData.OpcUaNodeId;
}
return string.Empty;
}
}
/// <summary>
/// 创建时间。
/// </summary>
public DateTime CreateTime { get; set; } = DateTime.Now;
/// <summary>
/// 更新时间。
/// </summary>
public DateTime UpdateTime { get; set; } = DateTime.Now;
/// <summary>
/// 导航属性:关联的变量数据。
/// </summary>
public VariableData? VariableData { get; set; }
/// <summary>
/// 导航属性关联的MQTT服务器。
/// </summary>
public Mqtt? Mqtt { get; set; }
}

View File

@@ -0,0 +1,34 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using PMSWPF.Models;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
namespace PMSWPF.ViewModels.Dialogs;
public partial class MqttAliasBatchEditDialogViewModel : ObservableObject
{
[ObservableProperty]
private string _title = "批量设置MQTT别名";
[ObservableProperty]
private ObservableCollection<VariableMqtt> _variablesToEdit;
public Mqtt SelectedMqtt { get; private set; }
public MqttAliasBatchEditDialogViewModel(List<VariableData> selectedVariables, Mqtt selectedMqtt)
{
SelectedMqtt = selectedMqtt;
Title=$"设置:{SelectedMqtt.Name}-MQTT服务器关联变量的别名";
VariablesToEdit = new ObservableCollection<VariableMqtt>(
selectedVariables.Select(v => new VariableMqtt(v, selectedMqtt))
);
}
public MqttAliasBatchEditDialogViewModel()
{
// For design time
VariablesToEdit = new ObservableCollection<VariableMqtt>();
}
}

View File

@@ -0,0 +1,34 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
namespace PMSWPF.ViewModels.Dialogs;
public partial class MqttAliasDialogViewModel : ObservableObject
{
[ObservableProperty]
private string _title = "设置MQTT别名";
[ObservableProperty]
private string _message = "请输入变量在该MQTT服务器上的别名";
[ObservableProperty]
private string _variableName = string.Empty;
[ObservableProperty]
private string _mqttServerName = string.Empty;
[ObservableProperty]
private string _mqttAlias = string.Empty;
public MqttAliasDialogViewModel(string variableName, string mqttServerName)
{
VariableName = variableName;
MqttServerName = mqttServerName;
Message = $"请输入变量 '{VariableName}' 在MQTT服务器 '{MqttServerName}' 上的别名:";
}
public MqttAliasDialogViewModel()
{
}
}

View File

@@ -0,0 +1,38 @@
<ui:ContentDialog
x:Class="PMSWPF.Views.Dialogs.MqttAliasBatchEditDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:vm="clr-namespace:PMSWPF.ViewModels.Dialogs"
xmlns:models="clr-namespace:PMSWPF.Models"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:MqttAliasBatchEditDialogViewModel}"
Title="{Binding Title}"
PrimaryButtonText="确定"
CloseButtonText="取消"
>
<StackPanel Margin="10">
<TextBlock TextWrapping="WrapWithOverflow" Margin="5 10" FontSize="13" Foreground="#666">设置的别名当变量向MQTT服务器发送数据时就会按照设置设置好的别名发送请在MQTT服务端按照设置的名称接受。</TextBlock>
<DataGrid ItemsSource="{Binding VariablesToEdit}"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
IsReadOnly="False">
<DataGrid.Columns>
<DataGridTextColumn Header="变量名称" Binding="{Binding VariableData.Name}" IsReadOnly="True" Width="*"/>
<DataGridTextColumn Header="标识符" Binding="{Binding Identifier}" IsReadOnly="True" Width="*"/>
<DataGridTemplateColumn Header="MQTT别名" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<hc:TextBox Text="{Binding MqttAlias, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
hc:InfoElement.Placeholder="请输入别名"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</ui:ContentDialog>

View File

@@ -0,0 +1,13 @@
using iNKORE.UI.WPF.Modern.Controls;
using PMSWPF.ViewModels.Dialogs;
namespace PMSWPF.Views.Dialogs;
public partial class MqttAliasBatchEditDialog : ContentDialog
{
public MqttAliasBatchEditDialog(MqttAliasBatchEditDialogViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}

View File

@@ -0,0 +1,23 @@
<ui:ContentDialog
x:Class="PMSWPF.Views.Dialogs.MqttAliasDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:vm="clr-namespace:PMSWPF.ViewModels.Dialogs"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance vm:MqttAliasDialogViewModel}"
Title="{Binding Title}"
PrimaryButtonText="确定"
CloseButtonText="取消">
<Grid>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Message}" Margin="0,0,0,10" TextWrapping="Wrap"/>
<hc:TextBox Text="{Binding MqttAlias, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
hc:InfoElement.Title="MQTT别名"
hc:InfoElement.Placeholder="请输入别名"/>
</StackPanel>
</Grid>
</ui:ContentDialog>

View File

@@ -0,0 +1,13 @@
using iNKORE.UI.WPF.Modern.Controls;
using PMSWPF.ViewModels.Dialogs;
namespace PMSWPF.Views.Dialogs;
public partial class MqttAliasDialog : ContentDialog
{
public MqttAliasDialog(MqttAliasDialogViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
}