diff --git a/DMS.Application/DTOs/Events/NlogChangedEventArgs.cs b/DMS.Application/DTOs/Events/NlogChangedEventArgs.cs
new file mode 100644
index 0000000..2f03f2c
--- /dev/null
+++ b/DMS.Application/DTOs/Events/NlogChangedEventArgs.cs
@@ -0,0 +1,25 @@
+using System;
+
+namespace DMS.Application.DTOs.Events
+{
+ ///
+ /// Nlog日志变更事件参数
+ ///
+ public class NlogChangedEventArgs : DataChangedEventArgs
+ {
+ ///
+ /// 变更的日志DTO
+ ///
+ public NlogDto Nlog { get; }
+
+ ///
+ /// 构造函数
+ ///
+ /// 变更类型
+ /// 变更的日志DTO
+ public NlogChangedEventArgs(DataChangeType changeType, NlogDto nlog) : base(changeType)
+ {
+ Nlog = nlog;
+ }
+ }
+}
\ No newline at end of file
diff --git a/DMS.Application/Interfaces/IDataCenterService.cs b/DMS.Application/Interfaces/IDataCenterService.cs
index 3feceef..459117f 100644
--- a/DMS.Application/Interfaces/IDataCenterService.cs
+++ b/DMS.Application/Interfaces/IDataCenterService.cs
@@ -261,6 +261,45 @@ public interface IDataCenterService
#endregion
+ #region 日志管理
+
+ ///
+ /// 异步根据ID获取日志DTO。
+ ///
+ Task GetNlogByIdAsync(int id);
+
+ ///
+ /// 异步获取所有日志DTO列表。
+ ///
+ Task> GetAllNlogsAsync();
+
+ ///
+ /// 异步获取指定数量的最新日志DTO列表。
+ ///
+ Task> GetLatestNlogsAsync(int count);
+
+ ///
+ /// 异步清空所有日志。
+ ///
+ Task ClearAllNlogsAsync();
+
+ ///
+ /// 在内存中添加日志
+ ///
+ void AddNlogToMemory(NlogDto nlogDto);
+
+ ///
+ /// 在内存中更新日志
+ ///
+ void UpdateNlogInMemory(NlogDto nlogDto);
+
+ ///
+ /// 在内存中删除日志
+ ///
+ void RemoveNlogFromMemory(int nlogId);
+
+ #endregion
+
#region 数据存储访问
///
@@ -291,6 +330,11 @@ public interface IDataCenterService
/// 获取所有MQTT服务器的安全字典。
///
ConcurrentDictionary MqttServers { get; }
+
+ ///
+ /// 获取所有日志的安全字典。
+ ///
+ ConcurrentDictionary Nlogs { get; }
#endregion
@@ -325,6 +369,11 @@ public interface IDataCenterService
/// 异步加载所有MQTT服务器数据。
///
Task> LoadAllMqttServersAsync();
+
+ ///
+ /// 异步加载所有日志数据。
+ ///
+ Task> LoadAllNlogsAsync();
#endregion
@@ -360,6 +409,10 @@ public interface IDataCenterService
///
event EventHandler MqttServerChanged;
+ ///
+ /// 当日志数据发生变化时触发
+ ///
+ event EventHandler NlogChanged;
///
/// 当变量值发生变化时触发
diff --git a/DMS.Application/Services/DataCenterService.cs b/DMS.Application/Services/DataCenterService.cs
index 0ab3d79..4fd66df 100644
--- a/DMS.Application/Services/DataCenterService.cs
+++ b/DMS.Application/Services/DataCenterService.cs
@@ -15,7 +15,7 @@ using System.Linq;
namespace DMS.Application.Services;
///
-/// 数据中心服务,负责管理所有的数据,包括设备、变量表、变量和菜单。
+/// 数据中心服务,负责管理所有的数据,包括设备、变量表、变量、菜单和日志。
/// 实现 接口。
///
public class DataCenterService : IDataCenterService
@@ -27,6 +27,7 @@ public class DataCenterService : IDataCenterService
private readonly IVariableAppService _variableAppService;
private readonly IMenuService _menuService;
private readonly IMqttAppService _mqttAppService;
+ private readonly INlogAppService _nlogAppService;
///
/// 安全字典,用于存储所有设备数据
@@ -58,6 +59,11 @@ public class DataCenterService : IDataCenterService
///
public ConcurrentDictionary MqttServers { get; } = new();
+ ///
+ /// 安全字典,用于存储所有日志数据
+ ///
+ public ConcurrentDictionary Nlogs { get; } = new();
+
#region 事件定义
///
@@ -90,6 +96,10 @@ public class DataCenterService : IDataCenterService
///
public event EventHandler MqttServerChanged;
+ ///
+ /// 当日志数据发生变化时触发
+ ///
+ public event EventHandler NlogChanged;
///
/// 当变量值发生变化时触发
@@ -108,6 +118,7 @@ public class DataCenterService : IDataCenterService
/// 变量应用服务实例。
/// 菜单服务实例。
/// MQTT应用服务实例。
+ /// Nlog应用服务实例。
public DataCenterService(
IRepositoryManager repositoryManager,
IMapper mapper,
@@ -115,7 +126,8 @@ public class DataCenterService : IDataCenterService
IVariableTableAppService variableTableAppService,
IVariableAppService variableAppService,
IMenuService menuService,
- IMqttAppService mqttAppService)
+ IMqttAppService mqttAppService,
+ INlogAppService nlogAppService)
{
_repositoryManager = repositoryManager;
_mapper = mapper;
@@ -124,6 +136,7 @@ public class DataCenterService : IDataCenterService
_variableAppService = variableAppService;
_menuService = menuService;
_mqttAppService = mqttAppService;
+ _nlogAppService = nlogAppService;
}
#region 设备管理
@@ -644,6 +657,7 @@ public class DataCenterService : IDataCenterService
Menus.Clear();
MenuTrees.Clear();
MqttServers.Clear();
+ Nlogs.Clear();
// 加载所有设备
var devices = await _repositoryManager.Devices.GetAllAsync();
@@ -662,6 +676,9 @@ public class DataCenterService : IDataCenterService
var menuDtos = _mapper.Map>(menus);
var mqttServers = await LoadAllMqttServersAsync();
+
+ // 加载所有日志
+ var nlogs = await LoadAllNlogsAsync();
var variableMqttAliases = await _repositoryManager.VariableMqttAliases.GetAllAsync();
@@ -696,6 +713,12 @@ public class DataCenterService : IDataCenterService
{
MqttServers.TryAdd(mqttServer.Id, mqttServer);
}
+
+ // 加载日志数据到内存
+ foreach (var nlog in nlogs)
+ {
+ Nlogs.TryAdd(nlog.Id, nlog);
+ }
// 将变量添加到安全字典
foreach (var variableDto in variableDtos)
@@ -783,6 +806,14 @@ public class DataCenterService : IDataCenterService
{
return await _mqttAppService.GetAllMqttServersAsync();
}
+
+ ///
+ /// 异步加载所有日志数据。
+ ///
+ public async Task> LoadAllNlogsAsync()
+ {
+ return await _nlogAppService.GetAllLogsAsync();
+ }
#endregion
@@ -836,6 +867,14 @@ public class DataCenterService : IDataCenterService
MqttServerChanged?.Invoke(this, e);
}
+ ///
+ /// 触发日志变更事件
+ ///
+ protected virtual void OnNlogChanged(NlogChangedEventArgs e)
+ {
+ NlogChanged?.Invoke(this, e);
+ }
+
///
/// 触发变量值变更事件
@@ -846,7 +885,7 @@ public class DataCenterService : IDataCenterService
}
#endregion
-
+
#region 私有辅助方法
///
@@ -868,4 +907,71 @@ public class DataCenterService : IDataCenterService
}
#endregion
+
+ #region 日志管理
+
+ ///
+ /// 异步根据ID获取日志DTO。
+ ///
+ public async Task GetNlogByIdAsync(int id)
+ {
+ return await _nlogAppService.GetLogByIdAsync(id);
+ }
+
+ ///
+ /// 异步获取所有日志DTO列表。
+ ///
+ public async Task> GetAllNlogsAsync()
+ {
+ return await _nlogAppService.GetAllLogsAsync();
+ }
+
+ ///
+ /// 异步获取指定数量的最新日志DTO列表。
+ ///
+ public async Task> GetLatestNlogsAsync(int count)
+ {
+ return await _nlogAppService.GetLatestLogsAsync(count);
+ }
+
+ ///
+ /// 异步清空所有日志。
+ ///
+ public async Task ClearAllNlogsAsync()
+ {
+ await _nlogAppService.ClearAllLogsAsync();
+ }
+
+ ///
+ /// 在内存中添加日志
+ ///
+ public void AddNlogToMemory(NlogDto nlogDto)
+ {
+ if (Nlogs.TryAdd(nlogDto.Id, nlogDto))
+ {
+ OnNlogChanged(new NlogChangedEventArgs(DataChangeType.Added, nlogDto));
+ }
+ }
+
+ ///
+ /// 在内存中更新日志
+ ///
+ public void UpdateNlogInMemory(NlogDto nlogDto)
+ {
+ Nlogs.AddOrUpdate(nlogDto.Id, nlogDto, (key, oldValue) => nlogDto);
+ OnNlogChanged(new NlogChangedEventArgs(DataChangeType.Updated, nlogDto));
+ }
+
+ ///
+ /// 在内存中删除日志
+ ///
+ public void RemoveNlogFromMemory(int nlogId)
+ {
+ if (Nlogs.TryRemove(nlogId, out var nlogDto))
+ {
+ OnNlogChanged(new NlogChangedEventArgs(DataChangeType.Deleted, nlogDto));
+ }
+ }
+
+ #endregion
}
\ No newline at end of file
diff --git a/DMS.Core/Enums/LoadTypes.cs b/DMS.Core/Enums/LoadTypes.cs
index 45a3d85..808dd8a 100644
--- a/DMS.Core/Enums/LoadTypes.cs
+++ b/DMS.Core/Enums/LoadTypes.cs
@@ -5,5 +5,6 @@ public enum LoadTypes
Devices,
Menu,
Mqtts,
+ Logs,
All
}
\ No newline at end of file
diff --git a/DMS.WPF/App.xaml.cs b/DMS.WPF/App.xaml.cs
index b3fc0b4..0002c7e 100644
--- a/DMS.WPF/App.xaml.cs
+++ b/DMS.WPF/App.xaml.cs
@@ -277,7 +277,9 @@ public partial class App : System.Windows.Application
provider.GetRequiredService(),
provider.GetRequiredService(),
provider.GetRequiredService(),
- provider.GetRequiredService()
+ provider.GetRequiredService(),
+ provider.GetRequiredService(),
+ provider.GetRequiredService()
)
);
services.AddScoped();
diff --git a/DMS.WPF/Services/DataServices.cs b/DMS.WPF/Services/DataServices.cs
index 84fca33..6081a17 100644
--- a/DMS.WPF/Services/DataServices.cs
+++ b/DMS.WPF/Services/DataServices.cs
@@ -12,6 +12,7 @@ using DMS.Core.Models;
using DMS.Message;
using DMS.WPF.ViewModels.Items;
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
+using ObservableCollections;
namespace DMS.WPF.Services;
@@ -50,6 +51,10 @@ public partial class DataServices : ObservableObject, IRecipient, I
[ObservableProperty]
private ObservableCollection _mqttServers;
+ // 日志列表。
+ [ObservableProperty]
+ private ObservableCollection _nlogs;
+
// 设备列表变更事件,当设备列表数据更新时触发。
public event Action> OnDeviceListChanged;
@@ -79,6 +84,37 @@ public partial class DataServices : ObservableObject, IRecipient, I
}));
}
+ ///
+ /// 处理日志变更事件
+ ///
+ private void OnNlogChanged(object sender, NlogChangedEventArgs e)
+ {
+ // 在UI线程上更新日志
+ App.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ switch (e.ChangeType)
+ {
+ case DataChangeType.Added:
+ Nlogs.Add(_mapper.Map(e.Nlog));
+ break;
+ case DataChangeType.Updated:
+ var existingLog = Nlogs.FirstOrDefault(l => l.Id == e.Nlog.Id);
+ if (existingLog != null)
+ {
+ _mapper.Map(e.Nlog, existingLog);
+ }
+ break;
+ case DataChangeType.Deleted:
+ var logToRemove = Nlogs.FirstOrDefault(l => l.Id == e.Nlog.Id);
+ if (logToRemove != null)
+ {
+ Nlogs.Remove(logToRemove);
+ }
+ break;
+ }
+ }));
+ }
+
///
/// DataServices类的构造函数。
@@ -98,10 +134,13 @@ public partial class DataServices : ObservableObject, IRecipient, I
Menus = new ObservableCollection();
MenuTrees = new ObservableCollection();
MqttServers = new ObservableCollection();
+ Nlogs = new ObservableCollection();
// 监听变量值变更事件
_dataCenterService.VariableValueChanged += OnVariableValueChanged;
_dataCenterService.OnLoadDataCompleted += OnLoadDataCompleted;
+ // 监听日志变更事件
+ _dataCenterService.NlogChanged += OnNlogChanged;
// 注册消息接收
// WeakReferenceMessenger.Register(this, (r, m) => r.Receive(m));
@@ -144,6 +183,9 @@ public partial class DataServices : ObservableObject, IRecipient, I
// 加载MQTT服务器数据
MqttServers = _mapper.Map>(_dataCenterService.MqttServers.Values);
+
+ // 加载日志数据
+ Nlogs = _mapper.Map>(_dataCenterService.Nlogs.Values);
BuildMenuTrees();
}
@@ -477,6 +519,9 @@ public partial class DataServices : ObservableObject, IRecipient, I
case LoadTypes.Mqtts:
_ = Task.Run(async () => await LoadMqttServers(_mqttAppService));
break;
+ case LoadTypes.Logs:
+ // 日志数据已在IDataCenterService中处理
+ break;
case LoadTypes.All:
// 加载所有数据
LoadAllDatas();
diff --git a/DMS.WPF/ViewModels/Items/NlogItemViewModel.cs b/DMS.WPF/ViewModels/Items/NlogItemViewModel.cs
index 32d34c4..6fc76cb 100644
--- a/DMS.WPF/ViewModels/Items/NlogItemViewModel.cs
+++ b/DMS.WPF/ViewModels/Items/NlogItemViewModel.cs
@@ -7,6 +7,11 @@ public class NlogItemViewModel : ObservableObject
{
private Nlog _nlog;
+ public NlogItemViewModel()
+ {
+ _nlog = new Nlog();
+ }
+
public NlogItemViewModel(Nlog nlog)
{
_nlog = nlog;
diff --git a/DMS.WPF/ViewModels/LogHistoryViewModel.cs b/DMS.WPF/ViewModels/LogHistoryViewModel.cs
index 4fb9aeb..fb2f4da 100644
--- a/DMS.WPF/ViewModels/LogHistoryViewModel.cs
+++ b/DMS.WPF/ViewModels/LogHistoryViewModel.cs
@@ -15,15 +15,19 @@ using DMS.WPF.ViewModels.Dialogs;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.ObjectModel;
using System;
+using DMS.WPF.Services;
+using DMS.Application.DTOs.Events;
namespace DMS.WPF.ViewModels;
-partial class LogHistoryViewModel : ViewModelBase
+partial class LogHistoryViewModel : ViewModelBase,IDisposable
{
+ public DataServices DataServices { get; }
private readonly IMapper _mapper;
private readonly INlogAppService _nlogAppService;
private readonly IDialogService _dialogService;
private readonly INotificationService _notificationService;
+ private readonly IDataCenterService _dataCenterService;
[ObservableProperty]
private NlogItemViewModel _selectedLog;
@@ -43,16 +47,85 @@ partial class LogHistoryViewModel : ViewModelBase
public ObservableCollection LogLevels { get; } = new ObservableCollection { "Trace", "Debug", "Info", "Warn", "Error", "Fatal" };
- public LogHistoryViewModel(IMapper mapper, INlogAppService nlogAppService, IDialogService dialogService, INotificationService notificationService)
+ public LogHistoryViewModel(IMapper mapper, INlogAppService nlogAppService, IDialogService dialogService,
+ INotificationService notificationService, DataServices dataServices, IDataCenterService dataCenterService)
{
_mapper = mapper;
_nlogAppService = nlogAppService;
_dialogService = dialogService;
_notificationService = notificationService;
+ DataServices = dataServices;
+ _dataCenterService = dataCenterService;
- _logItemList = new ObservableList();
+ _logItemList = new ObservableList(DataServices.Nlogs);
+
_synchronizedView = _logItemList.CreateView(v => v);
LogItemListView = _synchronizedView.ToNotifyCollectionChanged();
+
+ // 订阅日志变更事件
+ _dataCenterService.NlogChanged += OnNlogChanged;
+ }
+
+ ///
+ /// 处理日志变更事件
+ ///
+ private void OnNlogChanged(object sender, NlogChangedEventArgs e)
+ {
+ // 在UI线程上更新日志
+ App.Current.Dispatcher.BeginInvoke(new Action(() =>
+ {
+ switch (e.ChangeType)
+ {
+ case DataChangeType.Added:
+ var newLogItem = new NlogItemViewModel(new Nlog
+ {
+ Id = e.Nlog.Id,
+ LogTime = e.Nlog.LogTime,
+ Level = e.Nlog.Level,
+ ThreadId = e.Nlog.ThreadId,
+ ThreadName = e.Nlog.ThreadName,
+ Callsite = e.Nlog.Callsite,
+ CallsiteLineNumber = e.Nlog.CallsiteLineNumber,
+ Message = e.Nlog.Message,
+ Logger = e.Nlog.Logger,
+ Exception = e.Nlog.Exception,
+ CallerFilePath = e.Nlog.CallerFilePath,
+ CallerLineNumber = e.Nlog.CallerLineNumber,
+ CallerMember = e.Nlog.CallerMember
+ });
+ _logItemList.Add(newLogItem);
+ break;
+ case DataChangeType.Updated:
+ var existingLog = _logItemList.FirstOrDefault(l => l.Id == e.Nlog.Id);
+ if (existingLog != null)
+ {
+ existingLog = new NlogItemViewModel(new Nlog
+ {
+ Id = e.Nlog.Id,
+ LogTime = e.Nlog.LogTime,
+ Level = e.Nlog.Level,
+ ThreadId = e.Nlog.ThreadId,
+ ThreadName = e.Nlog.ThreadName,
+ Callsite = e.Nlog.Callsite,
+ CallsiteLineNumber = e.Nlog.CallsiteLineNumber,
+ Message = e.Nlog.Message,
+ Logger = e.Nlog.Logger,
+ Exception = e.Nlog.Exception,
+ CallerFilePath = e.Nlog.CallerFilePath,
+ CallerLineNumber = e.Nlog.CallerLineNumber,
+ CallerMember = e.Nlog.CallerMember
+ });
+ }
+ break;
+ case DataChangeType.Deleted:
+ var logToRemove = _logItemList.FirstOrDefault(l => l.Id == e.Nlog.Id);
+ if (logToRemove != null)
+ {
+ _logItemList.Remove(logToRemove);
+ }
+ break;
+ }
+ }));
}
private bool FilterLogs(NlogItemViewModel item)
@@ -165,4 +238,11 @@ partial class LogHistoryViewModel : ViewModelBase
_notificationService.ShowError($"加载日志时发生错误: {ex.Message}", ex);
}
}
+
+ public void Dispose()
+ {
+ // 取消订阅事件
+ _dataCenterService.NlogChanged -= OnNlogChanged;
+
+ }
}
\ No newline at end of file