完成删除变量

This commit is contained in:
2025-08-24 17:48:33 +08:00
parent c813fe63c3
commit 1d8d4a7f5e
9 changed files with 171 additions and 266 deletions

View File

@@ -32,6 +32,11 @@ public interface IVariableAppService
/// </summary>
Task<bool> DeleteVariableAsync(int id);
/// <summary>
/// 异步批量删除变量。
/// </summary>
Task<bool> DeleteVariablesAsync(List<int> ids);
/// <summary>
/// 异步批量导入变量。
/// </summary>

View File

@@ -127,6 +127,43 @@ public class VariableAppService : IVariableAppService
}
}
/// <summary>
/// 异步批量删除变量(事务性操作)。
/// </summary>
/// <param name="ids">要删除的变量ID列表。</param>
/// <returns>如果删除成功则为 true否则为 false。</returns>
/// <exception cref="ArgumentException">如果ID列表为空或null。</exception>
/// <exception cref="ApplicationException">如果删除变量时发生错误。</exception>
public async Task<bool> DeleteVariablesAsync(List<int> ids)
{
if (ids == null || !ids.Any())
{
throw new ArgumentException("变量ID列表不能为空", nameof(ids));
}
try
{
await _repoManager.BeginTranAsync();
// 批量删除变量
var deletedCount = await _repoManager.Variables.DeleteByIdsAsync(ids);
// 检查是否所有变量都被成功删除
if (deletedCount != ids.Count)
{
throw new InvalidOperationException($"删除变量失败:请求删除 {ids.Count} 个变量,实际删除 {deletedCount} 个变量");
}
await _repoManager.CommitAsync();
return true;
}
catch (Exception ex)
{
await _repoManager.RollbackAsync();
throw new ApplicationException($"批量删除变量时发生错误,操作已回滚,错误信息:{ex.Message}", ex);
}
}
public async Task<bool> BatchImportVariablesAsync(List<VariableDto> variables)
{
try

View File

@@ -43,6 +43,12 @@ public interface IBaseRepository<T> where T : class
/// <param name="id">要删除的实体的主键ID。</param>
Task<int> DeleteByIdAsync(int id);
/// <summary>
/// 异步根据ID列表批量删除实体。
/// </summary>
/// <param name="ids">要删除的实体的主键ID列表。</param>
Task<int> DeleteByIdsAsync(List<int> ids);
/// <summary>
/// 从数据库获取数据。
/// </summary>

View File

@@ -116,6 +116,23 @@ public abstract class BaseRepository<TEntity>
return entity;
}
/// <summary>
/// 异步根据主键 ID 列表批量删除实体。
/// </summary>
/// <param name="ids">要删除的实体主键 ID 列表。</param>
/// <returns>返回受影响的行数。</returns>
public virtual async Task<int> DeleteByIdsAsync(List<int> ids)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var result = await Db.Deleteable<TEntity>()
.In(ids)
.ExecuteCommandAsync();
stopwatch.Stop();
NlogHelper.Info($"DeleteByIds {typeof(TEntity).Name}, Count: {ids.Count}, 耗时:{stopwatch.ElapsedMilliseconds}ms");
return result;
}
/// <summary>
/// 异步根据指定条件获取单个实体。
/// </summary>

View File

@@ -173,6 +173,23 @@ public class VariableRepository : BaseRepository<DbVariable>, IVariableRepositor
return result;
}
/// <summary>
/// 异步根据ID列表批量删除变量。
/// </summary>
/// <param name="ids">要删除变量的唯一标识符列表。</param>
/// <returns>受影响的行数。</returns>
public async Task<int> DeleteByIdsAsync(List<int> ids)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
var result = await Db.Deleteable<DbVariable>()
.In(ids)
.ExecuteCommandAsync();
stopwatch.Stop();
NlogHelper.Info($"Delete {typeof(DbVariable)},Count={ids.Count},耗时:{stopwatch.ElapsedMilliseconds}ms");
return result;
}
/// <summary>
/// 异步获取指定数量的变量。
/// </summary>

View File

@@ -612,4 +612,21 @@ public partial class DataServices : ObservableRecipient, IRecipient<LoadMessage>
}
}
}
public void DeleteVariableById(int id)
{
var variableItem = Variables.FirstOrDefault(v => v.Id == id);
if (variableItem == null)
{
return;
}
var variableTable = VariableTables.FirstOrDefault(vt => vt.Id == variableItem.VariableTableId);
variableTable.Variables.Remove(variableItem);
Variables.Remove(variableItem);
}
}

View File

@@ -1,26 +1,27 @@
using AutoMapper;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using DMS.Core.Enums;
using DMS.Core.Interfaces;
using DMS.Core.Models;
using DMS.WPF.Services;
using DMS.WPF.ViewModels.Dialogs;
using DMS.WPF.ViewModels.Items;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using DMS.Application.DTOs;
using DMS.Application.Interfaces;
using DMS.Application.Services;
using DMS.Core.Enums;
using DMS.Core.Interfaces;
using DMS.Core.Models;
using DMS.Helper;
using DMS.WPF.Services;
using DMS.WPF.ViewModels.Dialogs;
using DMS.WPF.ViewModels.Items;
using DMS.WPF.Views;
using HandyControl.Controls;
using HandyControl.Data;
using HandyControl.Tools.Extension;
using Microsoft.Extensions.DependencyInjection;
using ObservableCollections;
using System.Collections;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
namespace DMS.WPF.ViewModels;
@@ -56,6 +57,10 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable
[ObservableProperty]
private VariableItemViewModel _selectedVariable;
[ObservableProperty]
private IList _selectedVariables = new ArrayList();
/// <summary>
/// 用于过滤变量数据的搜索文本。
/// 通过 ObservableProperty 自动生成 SearchText 属性和 OnSearchTextChanged 方法。
@@ -168,83 +173,9 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable
public override void OnLoaded()
{
_variableItemList.AddRange(CurrentVariableTable.Variables);
//
// // 创建原始数据的深拷贝备份,用于在取消保存时还原
// var settings = new JsonSerializerSettings
// {
// ReferenceLoopHandling = ReferenceLoopHandling.Ignore
// };
// var serialized = JsonConvert.SerializeObject(Variables, settings);
// _originalVariables = JsonConvert.DeserializeObject<ObservableCollection<Variable>>(serialized);
//
// // 在数据加载完成后,将所有变量的 IsModified 状态重置为 false
// foreach (var variable in Variables)
// {
// variable.IsModified = false;
// }
// 标记加载完成
IsLoadCompletion = true;
}
/// <summary>
/// 当用户尝试退出当前视图时异步调用。
/// 检查是否有未保存的修改,并提示用户是否保存或放弃更改。
/// </summary>
/// <returns>如果可以安全退出则为 true否则为 false。</returns>
public override async Task<bool> OnExitAsync()
{
// 查找所有已修改的变量数据
var modifiedDatas = Variables.Where(d => d.IsModified == true)
.ToList();
// 如果没有修改,则直接允许退出
if (modifiedDatas.Count == 0)
return true;
// 提示用户有未保存的数据,询问是否离开
// var isExit = await _dialogService.ShowConfrimeDialog(
// "数据未保存", $"你有{modifiedDatas.Count}个修改的变量没有保存,离开后这些数据就可能丢失了确认要离开吗?", "离开");
// // 如果用户选择不离开(即不保存),则还原数据
// if (!isExit)
// {
// // 遍历所有已修改的数据,从原始备份中还原
// foreach (var modifiedData in modifiedDatas)
// {
// var oldData = _originalVariables.First(od => od.Id == modifiedData.Id);
// // 将原始数据复制回当前数据
// _mapper.Map(oldData, modifiedData);
// modifiedData.IsModified = false; // 重置修改状态
// }
//
// return false; // 不允许退出
// }
return true; // 允许退出
}
/// <summary>
/// 保存所有已修改的变量数据到数据库。
/// 此命令通常绑定到UI中的“保存”按钮。
/// </summary>
[RelayCommand]
private async void SaveModifiedVarData()
{
// // 查找所有已标记为修改的变量数据
// var modifiedDatas = Variables.Where(d => d.IsModified == true)
// .ToList();
// // 更新数据库中的这些数据
// await _varDataRepository.UpdateAsync(modifiedDatas);
//
// // 还原所有已保存数据的修改状态
// foreach (var modifiedData in modifiedDatas)
// {
// modifiedData.IsModified = false;
// }
//
// // 显示成功通知
// NotificationHelper.ShowSuccess($"修改的{modifiedDatas.Count}变量保存成功.");
}
/// <summary>
/// 编辑选定的变量数据。
@@ -447,58 +378,6 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable
// }
}
/// <summary>
/// 刷新数据列表高效地同步UI显示数据与数据库最新数据。
/// </summary>
private async Task RefreshDataView()
{
// // 从数据库加载最新的变量数据
// var latestVariables = await _varDataRepository.GetByVariableTableIdAsync(VariableTable.Id);
//
// // 将最新数据转换为字典,以便快速查找
// var latestVariablesDict = latestVariables.ToDictionary(v => v.Id);
//
// // 用于存储需要从 Variables 中移除的项
// var itemsToRemove = new List<Variable>();
//
// // 遍历当前 Variables 集合,处理删除和更新
// for (int i = Variables.Count - 1; i >= 0; i--)
// {
// var currentVariable = Variables[i];
// if (latestVariablesDict.TryGetValue(currentVariable.Id, out var newVariable))
// {
// // 如果存在于最新数据中,检查是否需要更新
// if (!currentVariable.Equals(newVariable))
// {
// // 使用 AutoMapper 更新现有对象的属性,保持对象引用不变
// _mapper.Map(newVariable, currentVariable);
// }
//
// // 从字典中移除已处理的项,剩余的将是新增项
// latestVariablesDict.Remove(currentVariable.Id);
// }
// else
// {
// // 如果不存在于最新数据中,则标记为删除
// itemsToRemove.Add(currentVariable);
// }
// }
//
// // 移除已标记的项
// foreach (var item in itemsToRemove)
// {
// Variables.Remove(item);
// }
//
// // 添加所有剩余在 latestVariablesDict 中的项(这些是新增项)
// foreach (var newVariable in latestVariablesDict.Values)
// {
// Variables.Add(newVariable);
// }
//
// // 刷新视图以应用所有更改
// VariableView.Refresh();
}
//
/// <summary>
@@ -554,48 +433,51 @@ partial class VariableTableViewModel : ViewModelBase, INavigatable
/// </summary>
/// <param name="variablesToDelete">要删除的变量数据列表。</param>
[RelayCommand]
public async Task DeleteVarData(List<Variable> variablesToDelete)
public async Task DeleteVariable()
{
// // 检查是否有变量被选中
// if (variablesToDelete == null || !variablesToDelete.Any())
// {
// NotificationHelper.ShowInfo("请选择要删除的变量");
// return;
// }
//
// // 拼接要删除的变量名称,用于确认提示
// var names = string.Join("、", variablesToDelete.Select(v => v.Name));
//
// // 显示确认删除对话框
// var confirm = await _dialogService.ShowConfrimeDialog(
// "删除确认",
// $"确定要删除选中的 {variablesToDelete.Count} 个变量吗?\n\n{names}",
// "删除");
//
// if (!confirm)
// return; // 如果用户取消删除,则返回
//
// try
// {
// // 从数据库中删除变量数据
// var result = await _varDataRepository.DeleteAsync(variablesToDelete);
// if (result > 0)
// {
// await RefreshDataView();
// // 显示成功通知
// NotificationHelper.ShowSuccess($"成功删除 {result} 个变量");
// }
// else
// {
// // 显示删除失败通知
// NotificationHelper.ShowError("删除变量失败");
// }
// }
// catch (Exception e)
// {
// // 捕获并显示错误通知
// NotificationHelper.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e);
// }
try
{
List<VariableItemViewModel> variablesToDelete = SelectedVariables.Cast<VariableItemViewModel>().ToList();
// 检查是否有变量被选中
if (variablesToDelete == null || !variablesToDelete.Any())
{
NotificationHelper.ShowInfo("请选择要删除的变量");
return;
}
// 拼接要删除的变量名称,用于确认提示
var names = string.Join("、", variablesToDelete.Select(v => v.Name));
// 显示确认删除对话框
ConfirmDialogViewModel confirmDialogViewModel = new ConfirmDialogViewModel("删除变量", $"确认要删除变量:{names},删除后不可恢复,确认要删除吗?", "删除变量");
var isDel = await _dialogService.ShowDialogAsync(confirmDialogViewModel);
if (!isDel)
return; // 如果用户取消删除,则返回
// 从数据库中删除变量数据
var result = await _variableAppService.DeleteVariablesAsync(variablesToDelete.Select(v => v.Id).ToList());
if (result)
{
foreach (var variable in variablesToDelete)
{
_variableItemList.Remove(variable);
_dataServices.DeleteVariableById(variable.Id);
}
// 显示成功通知
NotificationHelper.ShowSuccess($"成功删除 {variablesToDelete.Count} 个变量");
}
else
{
// 显示删除失败通知
NotificationHelper.ShowError("删除变量失败");
}
}
catch (Exception e)
{
// 捕获并显示错误通知
NotificationHelper.ShowError($"删除变量的过程中发生了不可预期的错误:{e.Message}", e);
}
}
/// <summary>

View File

@@ -6,6 +6,8 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:enums="clr-namespace:DMS.Core.Enums;assembly=DMS.Core"
xmlns:ex="clr-namespace:DMS.Extensions"
xmlns:helper="clr-namespace:DMS.WPF.Helper"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:ikw="http://schemas.inkore.net/lib/ui/wpf"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="http://schemas.inkore.net/lib/ui/wpf/modern"
@@ -61,19 +63,12 @@
</ui:AppBarButton.Icon>
</ui:AppBarButton>
<ui:AppBarButton Click="DeleteVarData_Click" Label="删除变量">
<ui:AppBarButton Command="{Binding DeleteVariableCommand}" Label="删除变量">
<ui:AppBarButton.Icon>
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Delete}" />
</ui:AppBarButton.Icon>
</ui:AppBarButton>
<ui:AppBarButton Command="{Binding SaveModifiedVarDataCommand}" Label="保存变量">
<ui:AppBarButton.Icon>
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Save}" />
</ui:AppBarButton.Icon>
</ui:AppBarButton>
<ui:AppBarButton
Command="{Binding ImprotFromTiaVarTableCommand}"
Label="从TIA变量表导入"
@@ -149,6 +144,10 @@
SelectedItem="{Binding SelectedVariable}"
SelectionMode="Extended"
Style="{StaticResource DataGridBaseStyle}">
<i:Interaction.Behaviors>
<helper:SelectedItemsBehavior SelectedItems="{Binding SelectedVariables}" />
</i:Interaction.Behaviors>
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem
@@ -167,16 +166,11 @@
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Edit}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Click="DeleteVarData_Click" Header="删除变量">
<MenuItem Command="{Binding DeleteVariableCommand}" Header="删除变量">
<MenuItem.Icon>
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Delete}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem Command="{Binding SaveModifiedVarDataCommand}" Header="保存变量">
<MenuItem.Icon>
<ui:FontIcon Icon="{x:Static ui:SegoeFluentIcons.Save}" />
</MenuItem.Icon>
</MenuItem>
<MenuItem
Command="{Binding ImprotFromTiaVarTableCommand}"
Header="从TIA变量表导入"

View File

@@ -48,75 +48,5 @@ public partial class VariableTableView : UserControl
IsLoadCompletion = true;
}
private void DataGrid_OnCellEditEnding(object? sender, DataGridCellEditEndingEventArgs args)
{
if (args.EditAction != DataGridEditAction.Commit)
return;
// try
// {
// // 获取到改变后的值和绑定的属性名
// Variable var = (Variable)args.Row.Item;
// var element = args.EditingElement;
// object newValue = null;
// string bindingPath = "";
//
// if (element is TextBox textBox)
// {
// newValue = textBox.Text;
// DataGridTextColumn textColumn = (DataGridTextColumn)args.Column;
// bindingPath = (textColumn.Binding as Binding)?.Path.Path;
// }
// else if (element is CheckBox checkBox)
// {
// newValue = checkBox.IsChecked;
// DataGridCheckBoxColumn checkBoxColumn = (DataGridCheckBoxColumn)args.Column;
// bindingPath = (checkBoxColumn.Binding as Binding)?.Path.Path;
// }
// else if (args.Column.Header.ToString() == "信号类型")
// {
// var comboBox = VisualTreeHelper.GetChild(element, 0) as ComboBox;
// if (comboBox != null)
// {
// newValue = comboBox.SelectedItem;
// bindingPath = "SignalType";
// }
// }
// else
// {
// return;
// }
//
// if (newValue == null || string.IsNullOrEmpty(bindingPath))
// return;
// // 通过反射拿到值
// var pathPropertyInfo = var.GetType()
// .GetProperty(bindingPath);
// var oldValue = pathPropertyInfo.GetValue(var);
// // 判断值是否相等
// if (newValue.ToString() != oldValue?.ToString())
// {
// var.IsModified = true;
// }
//
// }
// catch (Exception e)
// {
// NotificationHelper.ShowError("变量表编辑的过过程中发生了错误:" + e.Message, e);
// }
}
private async void DeleteVarData_Click(object sender, RoutedEventArgs e)
{
// _viewModel = (VariableTableViewModel)this.DataContext;
// var selectedVariables = BasicGridView.SelectedItems.Cast<Variable>().ToList();
// if (selectedVariables.Any())
// {
// await _viewModel.DeleteVarData(selectedVariables);
// }
// else
// {
// NotificationHelper.ShowInfo("请选择要删除的变量");
// }
}
}