完成设备详情页添加变量表

This commit is contained in:
2025-07-30 12:54:14 +08:00
parent 1ebc1a4df6
commit a62ee03933
12 changed files with 133 additions and 118 deletions

View File

@@ -9,7 +9,7 @@ namespace DMS.Application.Interfaces
{ {
Task<VariableTableDto> GetVariableTableByIdAsync(int id); Task<VariableTableDto> GetVariableTableByIdAsync(int id);
Task<List<VariableTableDto>> GetAllVariableTablesAsync(); Task<List<VariableTableDto>> GetAllVariableTablesAsync();
Task<VariableTableDto> CreateVariableTableAsync(CreateVariableTableWithMenuDto createDto); Task<CreateVariableTableWithMenuDto> CreateVariableTableAsync(CreateVariableTableWithMenuDto createDto);
Task<int> UpdateVariableTableAsync(VariableTableDto variableTableDto); Task<int> UpdateVariableTableAsync(VariableTableDto variableTableDto);
Task<bool> DeleteVariableTableAsync(int id); Task<bool> DeleteVariableTableAsync(int id);
} }

View File

@@ -56,7 +56,7 @@ namespace DMS.Application.Services
/// <param name="createDto">包含变量表和菜单信息的创建数据传输对象。</param> /// <param name="createDto">包含变量表和菜单信息的创建数据传输对象。</param>
/// <returns>创建后的变量表数据传输对象。</returns> /// <returns>创建后的变量表数据传输对象。</returns>
/// <exception cref="ApplicationException">如果添加变量表失败或找不到设备菜单。</exception> /// <exception cref="ApplicationException">如果添加变量表失败或找不到设备菜单。</exception>
public async Task<VariableTableDto> CreateVariableTableAsync(CreateVariableTableWithMenuDto createDto) public async Task<CreateVariableTableWithMenuDto> CreateVariableTableAsync(CreateVariableTableWithMenuDto createDto)
{ {
await _repositoryManager.BeginTranAsync(); await _repositoryManager.BeginTranAsync();
try try
@@ -70,6 +70,8 @@ namespace DMS.Application.Services
throw new ApplicationException($"添加变量表失败设备ID:{createDto.DeviceId},请检查。"); throw new ApplicationException($"添加变量表失败设备ID:{createDto.DeviceId},请检查。");
} }
_mapper.Map(createdVariableTable, createDto.VariableTable);
if (createDto.Menu!=null) if (createDto.Menu!=null)
{ {
// 获取设备菜单,作为变量表菜单的父级 // 获取设备菜单,作为变量表菜单的父级
@@ -84,16 +86,18 @@ namespace DMS.Application.Services
// 映射菜单实体并设置关联信息 // 映射菜单实体并设置关联信息
var menu = _mapper.Map<MenuBean>(createDto.Menu); var menu = _mapper.Map<MenuBean>(createDto.Menu);
menu.ParentId = deviceMenu.Id; menu.ParentId = deviceMenu.Id;
menu.TargetViewKey = "VariableTableMenu";
menu.TargetId = createdVariableTable.Id; menu.TargetId = createdVariableTable.Id;
menu.MenuType = MenuType.VariableTableMenu; menu.MenuType = MenuType.VariableTableMenu;
await _repositoryManager.Menus.AddAsync(menu); var addMenu= await _repositoryManager.Menus.AddAsync(menu);
_mapper.Map(addMenu, createDto.Menu);
} }
await _repositoryManager.CommitAsync(); await _repositoryManager.CommitAsync();
return _mapper.Map<VariableTableDto>(createdVariableTable); return createDto;
} }
catch catch
{ {

View File

@@ -26,7 +26,7 @@ public class VariableTableAppServiceTest : BaseServiceTest
DeviceId = 5 DeviceId = 5
}; };
var addVarTable= await _variableTableAppService.CreateVariableTableAsync(dto); var addVarTable= await _variableTableAppService.CreateVariableTableAsync(dto);
Assert.NotEqual(addVarTable.Id, 0); Assert.NotEqual(addVarTable.VariableTable.Id, 0);
} }
[Fact] [Fact]
@@ -40,16 +40,16 @@ public class VariableTableAppServiceTest : BaseServiceTest
DeviceId = 5 // Assuming a device with ID 5 exists for testing DeviceId = 5 // Assuming a device with ID 5 exists for testing
}; };
var createdVariableTable = await _variableTableAppService.CreateVariableTableAsync(createDto); var createdVariableTable = await _variableTableAppService.CreateVariableTableAsync(createDto);
Assert.NotEqual(createdVariableTable.Id, 0); Assert.NotEqual(createdVariableTable.VariableTable.Id, 0);
// Act: Delete the created variable table // Act: Delete the created variable table
var isDeleted = await _variableTableAppService.DeleteVariableTableAsync(createdVariableTable.Id); var isDeleted = await _variableTableAppService.DeleteVariableTableAsync(createdVariableTable.VariableTable.Id);
// Assert: Verify deletion was successful // Assert: Verify deletion was successful
Assert.True(isDeleted); Assert.True(isDeleted);
// Optionally, try to retrieve the deleted variable table to confirm it's gone // Optionally, try to retrieve the deleted variable table to confirm it's gone
var deletedTable = await _variableTableAppService.GetVariableTableByIdAsync(createdVariableTable.Id); var deletedTable = await _variableTableAppService.GetVariableTableByIdAsync(createdVariableTable.VariableTable.Id);
Assert.Null(deletedTable); Assert.Null(deletedTable);
} }
@@ -64,20 +64,20 @@ public class VariableTableAppServiceTest : BaseServiceTest
DeviceId = 5 // Assuming a device with ID 5 exists for testing DeviceId = 5 // Assuming a device with ID 5 exists for testing
}; };
var createdVariableTable = await _variableTableAppService.CreateVariableTableAsync(createDto); var createdVariableTable = await _variableTableAppService.CreateVariableTableAsync(createDto);
Assert.NotEqual(createdVariableTable.Id, 0); Assert.NotEqual(createdVariableTable.VariableTable.Id, 0);
// Modify some properties of the DTO // Modify some properties of the DTO
createdVariableTable.Name = "Updated Variable Table Name"; createdVariableTable.VariableTable.Name = "Updated Variable Table Name";
createdVariableTable.Description = "This is an updated description."; createdVariableTable.VariableTable.Description = "This is an updated description.";
// Act: Update the variable table // Act: Update the variable table
var affectedRows = await _variableTableAppService.UpdateVariableTableAsync(createdVariableTable); var affectedRows = await _variableTableAppService.UpdateVariableTableAsync(createdVariableTable.VariableTable);
// Assert: Verify update was successful // Assert: Verify update was successful
Assert.Equal(1, affectedRows); Assert.Equal(1, affectedRows);
// Retrieve the updated variable table to confirm changes // Retrieve the updated variable table to confirm changes
var updatedTable = await _variableTableAppService.GetVariableTableByIdAsync(createdVariableTable.Id); var updatedTable = await _variableTableAppService.GetVariableTableByIdAsync(createdVariableTable.VariableTable.Id);
Assert.NotNull(updatedTable); Assert.NotNull(updatedTable);
Assert.Equal("Updated Variable Table Name", updatedTable.Name); Assert.Equal("Updated Variable Table Name", updatedTable.Name);
Assert.Equal("This is an updated description.", updatedTable.Description); Assert.Equal("This is an updated description.", updatedTable.Description);

View File

@@ -84,7 +84,7 @@
<XamlRuntime>Wpf</XamlRuntime> <XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Update="Views\Dialogs\VarTableDialog.xaml"> <Page Update="Views\Dialogs\VariableTableDialog.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<XamlRuntime>Wpf</XamlRuntime> <XamlRuntime>Wpf</XamlRuntime>
<SubType>Designer</SubType> <SubType>Designer</SubType>

View File

@@ -485,11 +485,11 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
if (variableTableItemViewModel == null) if (variableTableItemViewModel == null)
return; return;
VariableTables.Add(variableTableItemViewModel);
var device = Devices.FirstOrDefault(d => d.Id == variableTableItemViewModel.DeviceId); var device = Devices.FirstOrDefault(d => d.Id == variableTableItemViewModel.DeviceId);
if (device != null) if (device != null)
{ {
device.VariableTables.Add(variableTableItemViewModel); device.VariableTables.Add(variableTableItemViewModel);
VariableTables.Add(variableTableItemViewModel);
} }
} }

View File

@@ -15,6 +15,7 @@ namespace DMS.WPF.Services
{ {
{ typeof(DeviceDialogViewModel), typeof(DeviceDialog) }, { typeof(DeviceDialogViewModel), typeof(DeviceDialog) },
{ typeof(ConfrimDialogViewModel), typeof(ConfirmDialog) }, { typeof(ConfrimDialogViewModel), typeof(ConfirmDialog) },
{ typeof(VariableTableDialogViewModel), typeof(VariableTableDialog) },
// { typeof(MqttDialogViewModel), typeof(MqttDialog) }, // Add other mappings here // { typeof(MqttDialogViewModel), typeof(MqttDialog) }, // Add other mappings here
// ... other dialogs // ... other dialogs
}; };

View File

@@ -1,16 +1,24 @@
using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Input;
using DMS.Application.DTOs;
using DMS.Application.Interfaces;
using DMS.Core.Enums; using DMS.Core.Enums;
using DMS.Helper;
using DMS.WPF.Services; using DMS.WPF.Services;
using DMS.Services; using DMS.Services;
using DMS.WPF.ViewModels.Dialogs;
using DMS.WPF.ViewModels.Items; using DMS.WPF.ViewModels.Items;
using iNKORE.UI.WPF.Modern.Common.IconKeys;
namespace DMS.WPF.ViewModels; namespace DMS.WPF.ViewModels;
public partial class DeviceDetailViewModel : ViewModelBase,INavigatable public partial class DeviceDetailViewModel : ViewModelBase, INavigatable
{ {
private readonly IMapper _mapper;
private readonly IDialogService _dialogService; private readonly IDialogService _dialogService;
private readonly INavigationService _navigationService; private readonly INavigationService _navigationService;
private readonly IVariableTableAppService _variableTableAppService;
public DataServices DataServices { get; set; } public DataServices DataServices { get; set; }
[ObservableProperty] [ObservableProperty]
@@ -19,80 +27,50 @@ public partial class DeviceDetailViewModel : ViewModelBase,INavigatable
[ObservableProperty] [ObservableProperty]
private VariableItemViewModel _selectedVariableTable; private VariableItemViewModel _selectedVariableTable;
public DeviceDetailViewModel(IDialogService dialogService,INavigationService navigationService, DataServices dataServices) public DeviceDetailViewModel(IMapper mapper, IDialogService dialogService, INavigationService navigationService,
DataServices dataServices, IVariableTableAppService variableTableAppService)
{ {
_mapper = mapper;
_dialogService = dialogService; _dialogService = dialogService;
_navigationService = navigationService; _navigationService = navigationService;
_variableTableAppService = variableTableAppService;
DataServices = dataServices; DataServices = dataServices;
} }
public override void OnLoaded()
{
// Ensure VariableTables is an ObservableCollection for UI binding
// if (_curentDevice.VariableTables != null &&
// !(_curentDevice.VariableTables is ObservableCollection<VariableTable>))
// {
// _curentDevice.VariableTables = new ObservableCollection<VariableTable>(_curentDevice.VariableTables);
// }
// else if (_curentDevice.VariableTables == null)
// {
// _curentDevice.VariableTables = new ObservableCollection<VariableTable>();
// }
}
[RelayCommand] [RelayCommand]
private async Task AddVariableTable() private async Task AddVariableTable()
{ {
// using var db = DbContext.GetInstance(); try
// try {
// { VariableTableDialogViewModel variableTableDialogViewModel = new VariableTableDialogViewModel()
// // 1. Show dialog to get new variable table details {
// var newVarTable = await _dialogService.ShowAddVarTableDialog(); PrimaryButContent = "添加变量表"
// if (newVarTable == null) return; // User cancelled };
// // 1. 显示添加设备对话框
// // 2. Set properties for the new variable table var variableTableItemViewModel = await _dialogService.ShowDialogAsync(variableTableDialogViewModel);
// newVarTable.DeviceId = CurrentDevice.Id; // 如果用户取消或对话框未返回设备,则直接返回
// newVarTable.ProtocolType = CurrentDevice.ProtocolType; if (variableTableItemViewModel == null)
// newVarTable.IsActive = true; {
// return;
// // 3. Find the parent menu for the current device }
// var parentMenu = DataServicesHelper.FindMenusForDevice(CurrentDevice, _dataServices.MenuTrees);
// if (parentMenu == null) CreateVariableTableWithMenuDto createDto = new CreateVariableTableWithMenuDto();
// { createDto.VariableTable = _mapper.Map<VariableTableDto>(variableTableItemViewModel);
// //NotificationHelper.ShowError("无法找到当前设备的父级菜单,无法添加变量表菜单。"); createDto.DeviceId = CurrentDevice.Id;
// return; createDto.Menu = new MenuBeanDto()
// } {
// Header = variableTableItemViewModel.Name,
// // 4. Start database transaction Icon = SegoeFluentIcons.DataSense.Glyph
// await db.BeginTranAsync(); };
// CreateVariableTableWithMenuDto
// // 5. AddAsync variable table to the database resCreateDto = await _variableTableAppService.CreateVariableTableAsync(createDto);
// var addedVarTable = await _varTableRepository.AddAsync(newVarTable, db); DataServices.AddVariableTable(_mapper.Map<VariableTableItemViewModel>(resCreateDto.VariableTable));
// DataServices.AddMenuItem(_mapper.Map<MenuItemViewModel>(resCreateDto.Menu));
// // 6. Create and add the corresponding menu item }
// var newMenu = new MenuBean catch (Exception ex)
// { {
// Name = addedVarTable.Name, NotificationHelper.ShowError($"添加变量表时发生错误: {ex.Message}", ex);
// DataId = addedVarTable.Id, }
// Type = MenuType.VariableTableMenu,
// ParentId = parentMenu.Id,
// Icon = iNKORE.UI.WPF.Modern.Common.IconKeys.SegoeFluentIcons.Tablet.Glyph
// };
// await _menuRepository.AddAsync(newMenu, db);
//
// // 7. Commit transaction
// await db.CommitTranAsync();
//
// // 8. Update UI
// CurrentDevice?.VariableTables?.Add(addedVarTable);
// MessageHelper.SendLoadMessage(Enums.LoadTypes.Menu); // Refresh the main navigation menu
// //NotificationHelper.ShowSuccess($"变量表 {addedVarTable.Name} 添加成功。");
// }
// catch (Exception ex)
// {
// await db.RollbackTranAsync();
// //NotificationHelper.ShowError($"添加变量表时发生错误: {ex.Message}", ex);
// }
} }
[RelayCommand] [RelayCommand]
@@ -224,20 +202,20 @@ public partial class DeviceDetailViewModel : ViewModelBase,INavigatable
public async Task OnNavigatedToAsync(MenuItemViewModel menu) public async Task OnNavigatedToAsync(MenuItemViewModel menu)
{ {
var device= DataServices.Devices.FirstOrDefault(d => d.Id == menu.TargetId); var device = DataServices.Devices.FirstOrDefault(d => d.Id == menu.TargetId);
if (device!=null) if (device != null)
{ {
CurrentDevice = device; CurrentDevice = device;
} }
} }
[RelayCommand] [RelayCommand]
public void NavigateToVariableTable() public void NavigateToVariableTable()
{ {
if (SelectedVariableTable == null) return; if (SelectedVariableTable == null) return;
var menu=DataServices.Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu && m.TargetId == SelectedVariableTable.Id); var menu = DataServices.Menus.FirstOrDefault(m => m.MenuType == MenuType.VariableTableMenu &&
if (menu==null) return; m.TargetId == SelectedVariableTable.Id);
if (menu == null) return;
_navigationService.NavigateToAsync(menu); _navigationService.NavigateToAsync(menu);
} }
} }

View File

@@ -1,14 +0,0 @@
using CommunityToolkit.Mvvm.ComponentModel;
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.ViewModels.Dialogs;
public partial class VarTableDialogViewModel:ObservableObject
{
[ObservableProperty]
private VariableTableItemViewModel variableTable;
[ObservableProperty]
private string title;
[ObservableProperty]
private string primaryButtonText;
}

View File

@@ -0,0 +1,36 @@
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.WPF.ViewModels.Items;
namespace DMS.WPF.ViewModels.Dialogs;
public partial class VariableTableDialogViewModel:DialogViewModelBase<VariableTableItemViewModel>
{
[ObservableProperty]
private VariableTableItemViewModel _variableTable;
public VariableTableDialogViewModel(VariableTableItemViewModel variableTable=null)
{
if (variableTable==null)
{
VariableTable = new VariableTableItemViewModel();
}
else
{
VariableTable = variableTable;
}
}
[RelayCommand]
public async void ParimaryButton()
{
await Close(VariableTable);
}
[RelayCommand]
public async void CancleButton()
{
await Close(null);
}
}

View File

@@ -17,7 +17,7 @@ public partial class VariableTableItemViewModel : ObservableObject
private string _description; private string _description;
[ObservableProperty] [ObservableProperty]
private bool _isActive; private bool _isActive=true;
[ObservableProperty] [ObservableProperty]
private int _deviceId; private int _deviceId;

View File

@@ -1,25 +1,30 @@
<ui:ContentDialog x:Class="DMS.WPF.Views.Dialogs.VarTableDialog" <ui:ContentDialog x:Class="DMS.WPF.Views.Dialogs.VariableTableDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf" xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern" xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:vmd="clr-namespace:DMS.WPF.ViewModels.Dialogs" xmlns:vmd="clr-namespace:DMS.WPF.ViewModels.Dialogs"
xmlns:ex="clr-namespace:DMS.Extensions"
xmlns:en="clr-namespace:DMS.Core.Enums"
Title="{Binding Title}" Title="{Binding Title}"
CloseButtonText="取消" CloseButtonText="取消"
DefaultButton="Primary" DefaultButton="Primary"
PrimaryButtonText="{Binding PrimaryButtonText}" PrimaryButtonText="{Binding PrimaryButContent}"
Background="#fff" Background="#fff"
d:DataContext="{d:DesignInstance vmd:VarTableDialogViewModel}" d:DataContext="{d:DesignInstance vmd:VariableTableDialogViewModel}"
mc:Ignorable="d"> mc:Ignorable="d">
<ui:ContentDialog.Resources> <i:Interaction.Triggers>
<i:EventTrigger EventName="PrimaryButtonClick">
<i:InvokeCommandAction Command="{Binding ParimaryButtonCommand}" />
</i:EventTrigger>
<i:EventTrigger EventName="CloseButtonClick">
<i:InvokeCommandAction Command="{Binding CancleButtonCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ui:ContentDialog.Resources> <ikw:SimpleStackPanel Width="300"
Grid.Column="0"
<ikw:SimpleStackPanel Width="300" Grid.Column="0"
Margin="10 10 20 10 " Margin="10 10 20 10 "
Spacing="12"> Spacing="12">
<!-- 设备名称 --> <!-- 设备名称 -->
@@ -34,6 +39,12 @@
<TextBox AcceptsReturn="True" <TextBox AcceptsReturn="True"
Text="{Binding VariableTable.Description, UpdateSourceTrigger=PropertyChanged}" /> Text="{Binding VariableTable.Description, UpdateSourceTrigger=PropertyChanged}" />
<CheckBox FontSize="16"
Content="是否启用变量表"
Margin="0 30 0 0"
IsChecked="{Binding VariableTable.IsActive}" />
</ikw:SimpleStackPanel> </ikw:SimpleStackPanel>
</ui:ContentDialog> </ui:ContentDialog>

View File

@@ -3,11 +3,10 @@ using iNKORE.UI.WPF.Modern.Controls;
namespace DMS.WPF.Views.Dialogs; namespace DMS.WPF.Views.Dialogs;
public partial class VarTableDialog : ContentDialog public partial class VariableTableDialog : ContentDialog
{ {
public VarTableDialog(VarTableDialogViewModel viewModel) public VariableTableDialog()
{ {
InitializeComponent(); InitializeComponent();
this.DataContext = viewModel;
} }
} }