diff --git a/App.xaml.cs b/App.xaml.cs index e39c707..d4d8534 100644 --- a/App.xaml.cs +++ b/App.xaml.cs @@ -23,19 +23,42 @@ namespace PMSWPF; public partial class App : Application { public App() + { + } + + public new static App Current => (App)Application.Current; + public IServiceProvider Services { get; set; } + + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + InitializeLog(); + InitializeServices(); + InitializeDataBase(); + InitializeMenu().Await((e) => { NotificationHelper.ShowMessage($"初始化主菜单失败:{e.Message}"); }, + () => { MessageHelper.SendLoadMessage(LoadTypes.Menu); }); + + MainWindow = Services.GetRequiredService(); + MainWindow.Show(); + } + + protected override void OnExit(ExitEventArgs e) + { + // 应用程序退出时,确保 NLog 缓冲区被清空 + LogManager.Shutdown(); + base.OnExit(e); + } + + private void InitializeServices() { var container = new ServiceCollection(); - - var nlog = LogManager.Setup().LoadConfigurationFromFile("Config/nlog.config").GetCurrentClassLogger(); - container.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.SetMinimumLevel(LogLevel.Trace); loggingBuilder.AddNLog(); }); - - + container.AddSingleton(); container.AddSingleton(); container.AddSingleton(); @@ -59,26 +82,45 @@ public partial class App : Application Services.GetRequiredService(); } - public new static App Current => (App)Application.Current; - public IServiceProvider Services { get; } - - protected override void OnStartup(StartupEventArgs e) + private void InitializeLog() { - base.OnStartup(e); - InitDB(); - InitMenu().Await((e) => - { - NotificationHelper.ShowMessage($"初始化主菜单失败:{e.Message}"); - }, () => - { - MessageHelper.SendLoadMessage(LoadTypes.Menu); - }); + LogManager.Setup().LoadConfigurationFromFile("Config/nlog.config").GetCurrentClassLogger(); - MainWindow = Services.GetRequiredService(); - MainWindow.Show(); + + // 捕获未处理的异常并记录 + AppDomain.CurrentDomain.UnhandledException += (sender, args) => + { + var ex = args.ExceptionObject as Exception; + if (ex != null) + { + // 可以使用一个专用的 Logger 来记录未处理异常 + LogManager.GetLogger("UnhandledExceptionLogger").Fatal(ex, "应用程序发生未处理的异常。"); + } + }; + + // 捕获 Dispatcher 线程上的未处理异常 (UI 线程) + this.DispatcherUnhandledException += (sender, args) => + { + LogManager.GetLogger("DispatcherExceptionLogger").Fatal(args.Exception, "UI 线程发生未处理的异常。"); + // 标记为已处理,防止应用程序崩溃 (生产环境慎用,可能掩盖问题) + // args.Handled = true; + }; + + // 如果您使用 Task (异步方法) 并且没有正确 await,可能会导致异常丢失, + // 可以通过以下方式捕获 Task 中的异常。 + TaskScheduler.UnobservedTaskException += (sender, args) => + { + LogManager.GetLogger("UnobservedTaskExceptionLogger").Fatal(args.Exception, "异步任务发生未观察到的异常。"); + // args.SetObserved(); // 标记为已观察,防止进程终止 + }; + + } - private async Task InitMenu() + /// + /// 初始化菜单 + /// + private async Task InitializeMenu() { using (var db = DbContext.GetInstance()) { @@ -91,7 +133,7 @@ public partial class App : Application { Name = "数据转换", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.ChromeSwitch.Glyph, ParentId = 0 }; var mqttMenu = new DbMenu() { Name = "Mqtt服务器", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Cloud.Glyph, ParentId = 0 }; - + var settingMenu = new DbMenu() { Name = "设置", Type = MenuType.MainMenu, Icon = SegoeFluentIcons.Settings.Glyph, ParentId = 0 }; var aboutMenu = new DbMenu() @@ -114,7 +156,7 @@ public partial class App : Application } } - private void InitDB() + private void InitializeDataBase() { var _db = DbContext.GetInstance(); _db.DbMaintenance.CreateDatabase(); @@ -122,8 +164,8 @@ public partial class App : Application _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); - _db.CodeFirst.InitTables(); - _db.CodeFirst.InitTables(); + _db.CodeFirst.InitTables(); + _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); _db.CodeFirst.InitTables(); diff --git a/Data/Entities/DbDataVariable.cs b/Data/Entities/DbVariableData.cs similarity index 78% rename from Data/Entities/DbDataVariable.cs rename to Data/Entities/DbVariableData.cs index 74a16d4..6da6f31 100644 --- a/Data/Entities/DbDataVariable.cs +++ b/Data/Entities/DbVariableData.cs @@ -4,8 +4,8 @@ using SqlSugar.DbConvert; namespace PMSWPF.Data.Entities; -[SugarTable("DataVariable")] -public class DbDataVariable +[SugarTable("VariableData")] +public class DbVariableData { [SugarColumn(IsPrimaryKey = true, IsIdentity = true)] //数据库是自增才配自增 public int Id { get; set; } @@ -28,13 +28,13 @@ public class DbDataVariable [SugarColumn(IsNullable = true)] public List? Mqtts { get; set; } - public string DataValue { get; set; } - public string DisplayValue { get; set; } + public string DataValue { get; set; } = String.Empty; + public string DisplayValue { get; set; } = String.Empty; public DateTime UpdateTime { get; set; } [SugarColumn(IsNullable = true)] public DbUser? UpdateUser { get; set; } - public string Converstion { get; set; } + public string Converstion { get; set; } = String.Empty; public bool IsDeleted { get; set; } public bool IsActive { get; set; } public bool IsSave { get; set; } @@ -43,6 +43,6 @@ public class DbDataVariable public double AlarmMin { get; set; } public double AlarmMax { get; set; } - [SugarColumn(ColumnDataType = "varchar(20)", SqlParameterDbType = typeof(EnumToStringConvert))] + [SugarColumn(ColumnDataType = "varchar(20)", IsNullable = true, SqlParameterDbType = typeof(EnumToStringConvert))] public SignalType SignalType { get; set; } } \ No newline at end of file diff --git a/Data/Entities/DbS7DataVariable.cs b/Data/Entities/DbVariableS7Data.cs similarity index 64% rename from Data/Entities/DbS7DataVariable.cs rename to Data/Entities/DbVariableS7Data.cs index 33cb430..8f254ac 100644 --- a/Data/Entities/DbS7DataVariable.cs +++ b/Data/Entities/DbVariableS7Data.cs @@ -3,6 +3,6 @@ namespace PMSWPF.Data.Entities; [SugarTable("S7DataVariable")] -public class DbS7DataVariable : DbDataVariable +public class DbVariableS7Data : DbVariableData { } \ No newline at end of file diff --git a/Data/Entities/DbVariableTable.cs b/Data/Entities/DbVariableTable.cs index 9048347..0f3f48a 100644 --- a/Data/Entities/DbVariableTable.cs +++ b/Data/Entities/DbVariableTable.cs @@ -18,8 +18,8 @@ public class DbVariableTable [SugarColumn(ColumnDataType = "varchar(20)", SqlParameterDbType = typeof(EnumToStringConvert))] public ProtocolType ProtocolType { get; set; } - [Navigate(NavigateType.OneToMany, nameof(DbDataVariable.VariableTableId))] - public List? DataVariables { get; set; } + [Navigate(NavigateType.OneToMany, nameof(DbVariableData.VariableTableId))] + public List? DataVariables { get; set; } [SugarColumn(IsNullable = true)] public int? DeviceId { get; set; } diff --git a/Data/Repositories/DeviceRepository.cs b/Data/Repositories/DeviceRepository.cs index 4444eef..627d3df 100644 --- a/Data/Repositories/DeviceRepository.cs +++ b/Data/Repositories/DeviceRepository.cs @@ -1,59 +1,46 @@ +using NLog; using PMSWPF.Data.Entities; +using PMSWPF.Enums; using PMSWPF.Extensions; +using PMSWPF.Helper; using PMSWPF.Models; using SqlSugar; namespace PMSWPF.Data.Repositories; -public class DeviceRepository +public class DeviceRepository { + private readonly MenuRepository _menuRepository; + private readonly VarTableRepository _varTableRepository; + private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); + public DeviceRepository() { - - } - /// - /// 添加设备 - /// - /// - /// - /// - public async Task Add(Device device) - { - using (var db=DbContext.GetInstance()) - { - var exist = await db.Queryable().Where(d => d.Name == device.Name).FirstAsync(); - if (exist != null) - throw new InvalidOperationException("设备名称已经存在。"); - var dbDevice = new DbDevice(); - device.CopyTo(dbDevice); - dbDevice.VariableTables = new List(); - // 添加默认变量表 - var dbVariableTable = new DbVariableTable(); - dbVariableTable.Name = "默认变量表"; - dbVariableTable.Description = "默认变量表"; - dbVariableTable.ProtocolType = dbDevice.ProtocolType; - dbDevice.VariableTables.Add(dbVariableTable); - var addDbDevice= await db.InsertNav(dbDevice).Include(d => d.VariableTables).ExecuteReturnEntityAsync(); - return addDbDevice.CopyTo(); - } - + _menuRepository=new MenuRepository(); + _varTableRepository=new VarTableRepository(); } + + + public async Task Edit(Device device) { - using (var db=DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { return await db.Updateable(device.CopyTo()).ExecuteCommandAsync(); } - } - + + /// + /// 获取设备列表 + /// + /// public async Task> GetAll() { using (var db = DbContext.GetInstance()) { - var dlist = await db.Queryable().Includes(d => d.VariableTables,dv=>dv.Device).ToListAsync(); + var dlist = await db.Queryable().Includes(d => d.VariableTables, dv => dv.Device).ToListAsync(); var devices = new List(); foreach (var dbDevice in dlist) { @@ -63,16 +50,14 @@ public class DeviceRepository return devices; } - } public async Task GetById(int id) { - using (var db=DbContext.GetInstance()) + using (var db = DbContext.GetInstance()) { return await db.Queryable().FirstAsync(p => p.Id == id); } - } public async Task DeleteById(int id) @@ -81,6 +66,78 @@ public class DeviceRepository { return await db.Deleteable(new DbDevice { Id = id }).ExecuteCommandAsync(); } - + } + + /// + /// 添加设备,包括菜单 + /// + /// + public async Task AddDeviceAndMenu(Device device) + { + var db = DbContext.GetInstance(); + try + { + // 开启事务 + await db.BeginTranAsync(); + // 2. 将设备添加到数据库 + var addDevice = await Add(device, db); + // 如果数据库添加失败 + if (addDevice == null) + { + string addDeviceErrorMsg = $"添加设备失败:{device.Name}"; + Logger.Error(addDeviceErrorMsg); + NotificationHelper.ShowMessage(addDeviceErrorMsg, NotificationType.Error); + return; // 提前返回 + } + + // 3. 设备成功添加到数据库,进行菜单添加 + // 这里立即发出成功的通知和日志 + string addDeviceSuccessMsg = $"添加设备成功:{device.Name}"; + Logger.Info(addDeviceSuccessMsg); + NotificationHelper.ShowMessage(addDeviceSuccessMsg, NotificationType.Success); + + // 4. 为新设备添加菜单 + var addDeviceMenuId = await _menuRepository.AddDeviceMenu(addDevice, db); + if (device.IsAddDefVarTable) + { + var defVarTable = await _varTableRepository.AddDeviceDefVarTable(addDevice, db); + await _menuRepository.AddDeviceDefTableMenu(device, addDeviceMenuId, defVarTable.Id,db); + } + + // 添加添加变量表的菜单 + await _menuRepository.AddVarTableMenu(addDevice,addDeviceMenuId, db); + await db.CommitTranAsync(); + // 菜单也添加成功,通知 UI 更新 + MessageHelper.SendLoadMessage(LoadTypes.Menu); + MessageHelper.SendLoadMessage(LoadTypes.Devices); + } + catch (Exception e) + { + // 中间出错了 回滚 + await db.RollbackTranAsync(); + // 捕获并记录所有未预期的异常 + string errorMsg = $"在添加设备过程中发生未预期错误:"; + Logger.Error(errorMsg+e); + NotificationHelper.ShowMessage(errorMsg+e.Message, NotificationType.Error); + + } + } + + /// + /// 单独添加设备,不包括菜单和变量表 + /// + /// + /// + /// + /// + private async Task Add(Device device, SqlSugarClient db) + { + var exist = await db.Queryable().Where(d => d.Name == device.Name).FirstAsync(); + if (exist != null) + throw new InvalidOperationException("设备名称已经存在。"); + var dbDevice = new DbDevice(); + device.CopyTo(dbDevice); + // 是否添加默认变量表 + return await db.Insertable(dbDevice).ExecuteReturnEntityAsync(); } } \ No newline at end of file diff --git a/Data/Repositories/MenuRepository.cs b/Data/Repositories/MenuRepository.cs index a804b79..45dfabc 100644 --- a/Data/Repositories/MenuRepository.cs +++ b/Data/Repositories/MenuRepository.cs @@ -3,6 +3,7 @@ using PMSWPF.Data.Entities; using PMSWPF.Enums; using PMSWPF.Extensions; using PMSWPF.Models; +using SqlSugar; namespace PMSWPF.Data.Repositories; @@ -47,63 +48,104 @@ public class MenuRepository return await db.Insertable(menu.CopyTo()).ExecuteCommandAsync(); } } - - - public async Task AddDeviceMenu(Device device) + + /// + /// 添加默认变量表的菜单 + /// + /// + /// + /// + /// + /// + public async Task AddDeviceDefTableMenu(Device device, int parentMenuId,int varTableId, SqlSugarClient db) { - using (var db = DbContext.GetInstance()) + var defVarTableMenu = new MenuBean() { - bool result = false; - var deviceMainMenu = await db.Queryable().FirstAsync(m => m.Name == "设备"); - if (deviceMainMenu == null) - throw new InvalidOperationException("没有找到设备菜单!!"); + Name = "默认变量表", + Icon = SegoeFluentIcons.Tablet.Glyph, + Type = MenuType.VariableTableMenu, + ParentId = parentMenuId, + DataId = varTableId + }; + var defTableRes = await db.Insertable(defVarTableMenu).ExecuteCommandAsync(); + return defTableRes; + } - // 添加菜单项 - MenuBean menu = new MenuBean() - { - Name = device.Name, - Type = MenuType.DeviceMenu, - DataId = device.Id, - Icon = SegoeFluentIcons.Devices4.Glyph, - }; + /// + /// 给设备添加默认变量表菜单 + /// + /// + /// + /// + // public async Task AddDeviceDefVarTableMenu(Device device) + // { + // var db = DbContext.GetInstance(); + // try + // { + // await db.BeginTranAsync(); + // bool result = false; + // var parentMenuId = await AddDeviceMenu(device, db); + // var defTableRes = await AddDeviceDefTableMenu(device, parentMenuId, db); + // var addTableRes = await AddVarTableMenu(parentMenuId, db); + // // if ((addTableRes + defTableRes) != 2) + // // { + // // // 如果出错删除原来添加的设备菜单 + // // await db.Deleteable().Where(m => m.Id == parentMenuId).ExecuteCommandAsync(); + // // throw new InvalidOperationException("添加默认变量表时发生了错误!!"); + // // } + // + // await db.CommitTranAsync(); + // return true; + // } + // catch (Exception e) + // { + // await db.RollbackTranAsync(); + // } + // finally + // { + // } + // } - menu.ParentId = deviceMainMenu.Id; - var addDeviceMenuId = await db.Insertable(menu.CopyTo()) - .ExecuteReturnIdentityAsync(); - if (addDeviceMenuId == 0) - throw new InvalidOperationException($"{menu.Name},设备菜单添加失败!!"); + public async Task AddVarTableMenu(DbDevice dbDevice, int parentMenuId, SqlSugarClient db) + { + var addVarTable = new MenuBean() + { + Name = "添加变量表", + Icon = SegoeFluentIcons.Add.Glyph, + Type = MenuType.AddVariableTableMenu, + ParentId = parentMenuId, + DataId = dbDevice.Id + }; + var addTableRes = await db.Insertable(addVarTable).ExecuteCommandAsync(); + return addTableRes; + } - var defVarTable = await db.Queryable() - .FirstAsync(v => v.DeviceId == device.Id && v.Name == "默认变量表"); - if (defVarTable == null) - throw new InvalidOperationException($"没有找到{device.Name}的默认变量表。"); - var defVarTableMenu = new MenuBean() - { - Name = "默认变量表", - Icon = SegoeFluentIcons.Tablet.Glyph, - Type = MenuType.VariableTableMenu, - ParentId = addDeviceMenuId, - DataId = defVarTable.Id - }; - var addVarTable = new MenuBean() - { - Name = "添加变量表", - Icon = SegoeFluentIcons.Add.Glyph, - Type = MenuType.AddVariableTableMenu, - ParentId = addDeviceMenuId, - }; - var defTableRes = await db.Insertable(defVarTableMenu).ExecuteCommandAsync(); - var addTableRes = await db.Insertable(addVarTable).ExecuteCommandAsync(); - if ((addTableRes + defTableRes) != 2) - { - // 如果出错删除原来添加的设备菜单 - await db.Deleteable().Where(m => m.Id == addDeviceMenuId).ExecuteCommandAsync(); - throw new InvalidOperationException("添加默认变量表时发生了错误!!"); - } + + /// + /// 添加设备菜单 + /// + /// + /// + /// + /// + public async Task AddDeviceMenu(DbDevice device, SqlSugarClient db) + { + var deviceMainMenu = await db.Queryable().FirstAsync(m => m.Name == "设备"); + if (deviceMainMenu == null) + throw new InvalidOperationException("没有找到设备菜单!!"); - - return true; - } + // 添加菜单项 + MenuBean menu = new MenuBean() + { + Name = device.Name, + Type = MenuType.DeviceMenu, + DataId = device.Id, + Icon = SegoeFluentIcons.Devices4.Glyph, + }; + menu.ParentId = deviceMainMenu.Id; + var addDeviceMenuId = await db.Insertable(menu.CopyTo()) + .ExecuteReturnIdentityAsync(); + return addDeviceMenuId; } public async Task Edit(MenuBean menu) diff --git a/Data/Repositories/VarTableRepository.cs b/Data/Repositories/VarTableRepository.cs index 692c8bd..a13812e 100644 --- a/Data/Repositories/VarTableRepository.cs +++ b/Data/Repositories/VarTableRepository.cs @@ -1,6 +1,9 @@ +using iNKORE.UI.WPF.Modern.Common.IconKeys; using PMSWPF.Data.Entities; +using PMSWPF.Enums; using PMSWPF.Extensions; using PMSWPF.Models; +using SqlSugar; namespace PMSWPF.Data.Repositories; @@ -15,10 +18,34 @@ public class VarTableRepository { using (var db = DbContext.GetInstance()) { - return await db.Insertable(varTable.CopyTo()).ExecuteReturnIdentityAsync(); + return await db.Insertable(varTable.CopyTo()) + .ExecuteReturnIdentityAsync(); } } + + /// + /// 添加默认变量表 + /// + /// + /// + /// + public async Task AddDeviceDefVarTable(DbDevice dbDevice, SqlSugarClient db) + { + + // 添加默认变量表 + dbDevice.VariableTables = new List(); + var dbVariableTable = new DbVariableTable(); + dbVariableTable.IsActive = true; + dbVariableTable.DeviceId=dbDevice.Id; + dbVariableTable.Name = "默认变量表"; + dbVariableTable.Description = "默认变量表"; + dbVariableTable.ProtocolType = dbDevice.ProtocolType; + dbDevice.VariableTables.Add(dbVariableTable); + return await db.Insertable(dbVariableTable).ExecuteReturnEntityAsync();; + } + + public async Task Edit(VariableTable variableTable) { using (var db = DbContext.GetInstance()) @@ -26,4 +53,4 @@ public class VarTableRepository return await db.Updateable(variableTable.CopyTo()).ExecuteCommandAsync(); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/Helper/NotificationHelper.cs b/Helper/NotificationHelper.cs index 0e085fe..7b2efea 100644 --- a/Helper/NotificationHelper.cs +++ b/Helper/NotificationHelper.cs @@ -1,4 +1,5 @@ using CommunityToolkit.Mvvm.Messaging; +using NLog; using PMSWPF.Enums; using PMSWPF.Message; @@ -6,9 +7,19 @@ namespace PMSWPF.Helper; public class NotificationHelper { + private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); public static void ShowMessage(string msg, NotificationType notificationType = NotificationType.Info, bool isGlobal = false) { + + if (notificationType==NotificationType.Error) + { + Logger.Error(msg); + } + else + { + Logger.Info(msg); + } WeakReferenceMessenger.Default.Send( new NotificationMessage(msg, notificationType)); } diff --git a/Models/Device.cs b/Models/Device.cs index 890f179..d94cf0c 100644 --- a/Models/Device.cs +++ b/Models/Device.cs @@ -15,6 +15,8 @@ public partial class Device : ObservableObject [ObservableProperty] private bool isActive = true; + [ObservableProperty] private bool isAddDefVarTable = true; + [ObservableProperty] private bool isRuning; [ObservableProperty] private string name; diff --git a/Models/DataVariable.cs b/Models/VariableData.cs similarity index 97% rename from Models/DataVariable.cs rename to Models/VariableData.cs index 0a894a1..f6c17f5 100644 --- a/Models/DataVariable.cs +++ b/Models/VariableData.cs @@ -2,7 +2,7 @@ namespace PMSWPF.Models; -public class DataVariable +public class VariableData { public int Id { get; set; } public string Name { get; set; } diff --git a/Models/VariableTable.cs b/Models/VariableTable.cs index 4535999..29dccc9 100644 --- a/Models/VariableTable.cs +++ b/Models/VariableTable.cs @@ -10,7 +10,7 @@ public partial class VariableTable:ObservableObject [ObservableProperty] private string description; public ProtocolType ProtocolType { get; set; } - public List DataVariables { get; set; } + public List DataVariables { get; set; } [ObservableProperty] private bool isActive; public int? DeviceId { get; set; } diff --git a/ViewModels/DevicesViewModel.cs b/ViewModels/DevicesViewModel.cs index 4601660..84caba7 100644 --- a/ViewModels/DevicesViewModel.cs +++ b/ViewModels/DevicesViewModel.cs @@ -2,6 +2,7 @@ using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Microsoft.Extensions.Logging; +using PMSWPF.Data; using PMSWPF.Data.Repositories; using PMSWPF.Enums; using PMSWPF.Helper; @@ -21,12 +22,14 @@ public partial class DevicesViewModel : ViewModelBase [ObservableProperty] private ObservableCollection _devices; [ObservableProperty] private Device _selectedDevice; private readonly MenuRepository _menuRepository; + private readonly VarTableRepository _varTableRepository; public DevicesViewModel( ILogger logger, IDialogService dialogService, DataServices dataServices ) { _deviceRepository = new DeviceRepository(); + _varTableRepository = new VarTableRepository(); _menuRepository = new MenuRepository(); _logger = logger; _dialogService = dialogService; @@ -36,89 +39,13 @@ public partial class DevicesViewModel : ViewModelBase _dataServices.OnDeviceListChanged += (devices) => { Devices = new ObservableCollection(devices); }; } - // /// - // /// 添加设备 - // /// - // [RelayCommand] - // public async void AddDevice() - // { - // Device device = null; - // try - // { - // device = await _dialogService.ShowAddDeviceDialog(); - // if (device != null) - // { - // device = await _deviceRepository.Add(device); - // if (device != null) - // { - // var msg = $"添加设备成功:{device.Name}"; - // _logger.LogInformation(msg); - // - // bool addMenuRes = await _menuRepository.AddDeviceMenu(device); - // if (addMenuRes) - // { - // // 通知更新菜单 - // MessageHelper.SendLoadMessage(LoadTypes.Menu); - // MessageHelper.SendLoadMessage(LoadTypes.Devices); - // NotificationHelper.ShowMessage(msg, NotificationType.Success); - // } - // else - // { - // var msgerr = $"给设备添加菜单失败:{device.Name}"; - // _logger.LogInformation(msgerr); - // NotificationHelper.ShowMessage(msgerr, NotificationType.Error); - // } - // } - // else - // { - // var msg = $"添加设备失败:{device.Name}"; - // _logger.LogInformation(msg); - // NotificationHelper.ShowMessage(msg, NotificationType.Error); - // } - // } - // } - // catch (Exception e) - // { - // var msg = $"添加设备失败:{e.Message}"; - // _logger.LogError(msg); - // NotificationHelper.ShowMessage(msg, NotificationType.Error); - // } - // } + /// -/// 辅助方法:处理成功通知和日志 -/// -private void HandleOperationSuccess(string entityType, string operation, string entityName) -{ - var message = $"{entityType}{operation}成功:{entityName}"; - _logger.LogInformation(message); - NotificationHelper.ShowMessage(message, NotificationType.Success); -} - -/// -/// 辅助方法:处理失败通知和日志 -/// -private void HandleOperationFailure(string entityType, string operation, string entityName, Exception ex = null) -{ - var message = $"{entityType}{operation}失败:{entityName}"; - if (ex != null) - { - _logger.LogError(ex, message); - } - else - { - _logger.LogError(message); - } - NotificationHelper.ShowMessage(message, NotificationType.Error); -} - -/// -/// 添加设备 -/// -[RelayCommand] -public async void AddDevice() -{ - try + /// 添加设备 + /// + [RelayCommand] + public async void AddDevice() { // 1. 显示添加设备对话框 var device = await _dialogService.ShowAddDeviceDialog(); @@ -128,43 +55,8 @@ public async void AddDevice() _logger.LogInformation("用户取消了添加设备操作。"); return; } - - // 2. 将设备添加到数据库 - var addedDevice = await _deviceRepository.Add(device); - // 如果数据库添加失败 - if (addedDevice == null) - { - HandleOperationFailure("设备", "添加", device.Name); - return; // 提前返回 - } - - // 3. 设备成功添加到数据库,进行菜单添加 - // 这里立即发出成功的通知和日志 - HandleOperationSuccess("设备", "添加", addedDevice.Name); - - // 4. 为新设备添加菜单 - bool menuAddedSuccessfully = await _menuRepository.AddDeviceMenu(addedDevice); - if (menuAddedSuccessfully) - { - // 菜单也添加成功,通知 UI 更新 - MessageHelper.SendLoadMessage(LoadTypes.Menu); - MessageHelper.SendLoadMessage(LoadTypes.Devices); - } - else - { - // 菜单添加失败,通知用户并记录日志 - HandleOperationFailure("设备", "添加菜单", addedDevice.Name); - // 考虑:如果菜单添加失败,是否需要回滚设备添加? - // 例如:await _deviceRepository.Delete(addedDevice.Id); - } + await _deviceRepository.AddDeviceAndMenu(device); } - catch (Exception e) - { - // 捕获并记录所有未预期的异常 - _logger.LogError(e, "在添加设备过程中发生未预期错误。"); - NotificationHelper.ShowMessage($"添加设备失败:{e.Message}", NotificationType.Error); - } -} /// @@ -183,12 +75,12 @@ public async void AddDevice() var editDievce = await _dialogService.ShowEditDeviceDialog(SelectedDevice); if (editDievce != null) - { + { // 更新菜单 var res = await _deviceRepository.Edit(editDievce); var menu = DataServicesHelper.FindMenusForDevice(editDievce, _dataServices.MenuTrees); if (menu != null) - await _menuRepository.Edit(menu); + await _menuRepository.Edit(menu); MessageHelper.SendLoadMessage(LoadTypes.Menu); MessageHelper.SendLoadMessage(LoadTypes.Devices); @@ -222,7 +114,7 @@ public async void AddDevice() var menu = DataServicesHelper.FindMenusForDevice(SelectedDevice, _dataServices.MenuTrees); if (menu != null) await _menuRepository.DeleteMenu(menu); - + MessageHelper.SendLoadMessage(LoadTypes.Menu); MessageHelper.SendLoadMessage(LoadTypes.Devices); NotificationHelper.ShowMessage($"删除设备成功,设备名:{SelectedDevice.Name}", NotificationType.Success); @@ -234,8 +126,4 @@ public async void AddDevice() _logger.LogError($"删除设备的过程中发生错误:{e}"); } } - - - - } \ No newline at end of file diff --git a/ViewModels/MainViewModel.cs b/ViewModels/MainViewModel.cs index c5ca0fe..8bbe789 100644 --- a/ViewModels/MainViewModel.cs +++ b/ViewModels/MainViewModel.cs @@ -77,6 +77,7 @@ public partial class MainViewModel : ViewModelBase break; case MenuType.AddVariableTableMenu: + await AddVariableTable(menu); break; } diff --git a/ViewModels/VariableTableViewModel.cs b/ViewModels/VariableTableViewModel.cs index 0f836be..8af44ad 100644 --- a/ViewModels/VariableTableViewModel.cs +++ b/ViewModels/VariableTableViewModel.cs @@ -12,7 +12,7 @@ partial class VariableTableViewModel : ViewModelBase { // private readonly ILogger _logger; [ObservableProperty] private VariableTable variableTable; - [ObservableProperty] private ObservableCollection _dataVariables; + [ObservableProperty] private ObservableCollection _dataVariables; /// /// 是否是第一次加载,防止ToggleSwitch第一次加载触发改变事件 @@ -35,7 +35,7 @@ partial class VariableTableViewModel : ViewModelBase if (VariableTable.DataVariables != null) { - DataVariables = new ObservableCollection(VariableTable.DataVariables); + DataVariables = new ObservableCollection(VariableTable.DataVariables); } IsLoadCompletion = true; } diff --git a/Views/Dialogs/DeviceDialog.xaml b/Views/Dialogs/DeviceDialog.xaml index c14576d..3dc7d61 100644 --- a/Views/Dialogs/DeviceDialog.xaml +++ b/Views/Dialogs/DeviceDialog.xaml @@ -61,19 +61,10 @@ - - - - - - - - - - + diff --git a/Views/Dialogs/DeviceDialog.xaml.cs b/Views/Dialogs/DeviceDialog.xaml.cs index 45bd919..ae1d998 100644 --- a/Views/Dialogs/DeviceDialog.xaml.cs +++ b/Views/Dialogs/DeviceDialog.xaml.cs @@ -13,33 +13,4 @@ public partial class DeviceDialog DataContext = viewModel; } - private void OnPrimaryButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - } - - - private void OnCloseButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args) - { - var deferral = args.GetDeferral(); - deferral.Complete(); - } - - private async void TryOpenAnother(object sender, RoutedEventArgs e) - { - // try - // { - // await new TestContentDialog { Owner = Owner }.ShowAsync(); - // } - // catch (Exception ex) - // { - // ErrorText.Text = ex.Message; - // ErrorText.Visibility = Visibility.Visible; - // } - } - - private void OnClosed(ContentDialog sender, ContentDialogClosedEventArgs args) - { - // ErrorText.Text = string.Empty; - // ErrorText.Visibility = Visibility.Collapsed; - } } \ No newline at end of file