修改历史记录功能(未完成)
This commit is contained in:
@@ -9,6 +9,7 @@ public class VariableHistoryDto
|
|||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public int VariableId { get; set; }
|
public int VariableId { get; set; }
|
||||||
|
public string VariableName { get; set; }
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
public DateTime Timestamp { get; set; }
|
public DateTime Timestamp { get; set; }
|
||||||
}
|
}
|
||||||
41
DMS.Application/Interfaces/IHistoryAppService.cs
Normal file
41
DMS.Application/Interfaces/IHistoryAppService.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using DMS.Application.DTOs;
|
||||||
|
|
||||||
|
namespace DMS.Application.Interfaces;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 定义历史记录管理相关的应用服务操作。
|
||||||
|
/// </summary>
|
||||||
|
public interface IHistoryAppService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取指定变量的历史记录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取指定变量的历史记录,支持条数限制和时间范围筛选。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId, int? limit = null, DateTime? startTime = null, DateTime? endTime = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取所有变量的历史记录。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有变量历史记录列表</returns>
|
||||||
|
Task<List<VariableHistoryDto>> GetAllVariableHistoriesAsync();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取所有变量的历史记录,支持条数限制和时间范围筛选。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>所有变量历史记录列表</returns>
|
||||||
|
Task<List<VariableHistoryDto>> GetAllVariableHistoriesAsync(int? limit = null, DateTime? startTime = null, DateTime? endTime = null);
|
||||||
|
}
|
||||||
@@ -70,11 +70,4 @@ public interface IVariableAppService
|
|||||||
/// <param name="variableToCheck">要检查的变量。</param>
|
/// <param name="variableToCheck">要检查的变量。</param>
|
||||||
/// <returns>如果变量已存在则返回该变量,否则返回null。</returns>
|
/// <returns>如果变量已存在则返回该变量,否则返回null。</returns>
|
||||||
Task<VariableDto?> FindExistingVariableAsync(VariableDto variableToCheck);
|
Task<VariableDto?> FindExistingVariableAsync(VariableDto variableToCheck);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步获取指定变量的历史记录。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variableId">变量ID</param>
|
|
||||||
/// <returns>变量历史记录列表</returns>
|
|
||||||
Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId);
|
|
||||||
}
|
}
|
||||||
@@ -40,7 +40,9 @@ public class MappingProfile : Profile
|
|||||||
.ReverseMap();
|
.ReverseMap();
|
||||||
|
|
||||||
// VariableHistory 映射
|
// VariableHistory 映射
|
||||||
CreateMap<VariableHistory, VariableHistoryDto>().ReverseMap();
|
CreateMap<VariableHistory, VariableHistoryDto>()
|
||||||
|
.ForMember(dest => dest.VariableName, opt => opt.MapFrom(src => src.Variable.Name))
|
||||||
|
.ReverseMap();
|
||||||
|
|
||||||
// MenuBean 映射
|
// MenuBean 映射
|
||||||
CreateMap<MenuBean, MenuBeanDto>().ReverseMap();
|
CreateMap<MenuBean, MenuBeanDto>().ReverseMap();
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ public class AppDataStorageService : IAppDataStorageService
|
|||||||
/// 安全字典,用于存储所有MQTT变量别名的数据
|
/// 安全字典,用于存储所有MQTT变量别名的数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public ConcurrentDictionary<int, VariableMqttAliasDto> VariableMqttAliases { get; } = new();
|
public ConcurrentDictionary<int, VariableMqttAliasDto> VariableMqttAliases { get; } = new();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 安全字典,用于存储所有历史记录
|
||||||
|
/// </summary>
|
||||||
|
public ConcurrentDictionary<int, VariableHistoryDto> VariableHistories { get; } = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 安全字典,用于存储所有日志数据
|
/// 安全字典,用于存储所有日志数据
|
||||||
|
|||||||
74
DMS.Application/Services/HistoryAppService.cs
Normal file
74
DMS.Application/Services/HistoryAppService.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using AutoMapper;
|
||||||
|
using DMS.Application.DTOs;
|
||||||
|
using DMS.Application.Interfaces;
|
||||||
|
using DMS.Core.Interfaces;
|
||||||
|
|
||||||
|
namespace DMS.Application.Services;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 历史记录应用服务实现类,负责处理变量历史记录相关的业务逻辑。
|
||||||
|
/// </summary>
|
||||||
|
public class HistoryAppService : IHistoryAppService
|
||||||
|
{
|
||||||
|
private readonly IRepositoryManager _repoManager;
|
||||||
|
private readonly IMapper _mapper;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 构造函数,注入仓储管理器和AutoMapper。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="repoManager">仓储管理器实例。</param>
|
||||||
|
/// <param name="mapper">AutoMapper实例。</param>
|
||||||
|
public HistoryAppService(IRepositoryManager repoManager, IMapper mapper)
|
||||||
|
{
|
||||||
|
_repoManager = repoManager;
|
||||||
|
_mapper = mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取指定变量的历史记录。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
public async Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId)
|
||||||
|
{
|
||||||
|
var histories = await _repoManager.VariableHistories.GetByVariableIdAsync(variableId);
|
||||||
|
return _mapper.Map<List<VariableHistoryDto>>(histories);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取指定变量的历史记录,支持条数限制和时间范围筛选。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
public async Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId, int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
|
{
|
||||||
|
var histories = await _repoManager.VariableHistories.GetByVariableIdAsync(variableId, limit, startTime, endTime);
|
||||||
|
return _mapper.Map<List<VariableHistoryDto>>(histories);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取所有变量的历史记录。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>所有变量历史记录列表</returns>
|
||||||
|
public async Task<List<VariableHistoryDto>> GetAllVariableHistoriesAsync()
|
||||||
|
{
|
||||||
|
var histories = await _repoManager.VariableHistories.GetAllAsync();
|
||||||
|
return _mapper.Map<List<VariableHistoryDto>>(histories);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 异步获取所有变量的历史记录,支持条数限制和时间范围筛选。
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>所有变量历史记录列表</returns>
|
||||||
|
public async Task<List<VariableHistoryDto>> GetAllVariableHistoriesAsync(int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
|
{
|
||||||
|
var histories = await _repoManager.VariableHistories.GetAllAsync(limit, startTime, endTime);
|
||||||
|
return _mapper.Map<List<VariableHistoryDto>>(histories);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -285,15 +285,4 @@ public class VariableAppService : IVariableAppService
|
|||||||
// 如果找到了匹配的变量,返回第一个(也是唯一一个)
|
// 如果找到了匹配的变量,返回第一个(也是唯一一个)
|
||||||
return existingVariables.FirstOrDefault();
|
return existingVariables.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 异步获取指定变量的历史记录。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variableId">变量ID</param>
|
|
||||||
/// <returns>变量历史记录列表</returns>
|
|
||||||
public async Task<List<VariableHistoryDto>> GetVariableHistoriesAsync(int variableId)
|
|
||||||
{
|
|
||||||
var histories = await _repoManager.VariableHistories.GetByVariableIdAsync(variableId);
|
|
||||||
return _mapper.Map<List<VariableHistoryDto>>(histories);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -10,4 +10,23 @@ public interface IVariableHistoryRepository:IBaseRepository<VariableHistory>
|
|||||||
/// <param name="variableId">变量ID</param>
|
/// <param name="variableId">变量ID</param>
|
||||||
/// <returns>变量历史记录列表</returns>
|
/// <returns>变量历史记录列表</returns>
|
||||||
Task<List<VariableHistory>> GetByVariableIdAsync(int variableId);
|
Task<List<VariableHistory>> GetByVariableIdAsync(int variableId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据变量ID获取历史记录,支持条数限制和时间范围筛选
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
Task<List<VariableHistory>> GetByVariableIdAsync(int variableId, int? limit = null, DateTime? startTime = null, DateTime? endTime = null);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有历史记录,支持条数限制和时间范围筛选
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>所有历史记录列表</returns>
|
||||||
|
Task<List<VariableHistory>> GetAllAsync(int? limit = null, DateTime? startTime = null, DateTime? endTime = null);
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@ public class VariableHistory
|
|||||||
{
|
{
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public int VariableId { get; set; }
|
public int VariableId { get; set; }
|
||||||
|
public Variable Variable { get; set; }
|
||||||
public string Value { get; set; } // 以字符串形式存储,便于通用性
|
public string Value { get; set; } // 以字符串形式存储,便于通用性
|
||||||
public DateTime Timestamp { get; set; }
|
public DateTime Timestamp { get; set; }
|
||||||
}
|
}
|
||||||
@@ -123,4 +123,64 @@ public class VariableHistoryRepository : BaseRepository<DbVariableHistory>, IVar
|
|||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
return _mapper.Map<List<VariableHistory>>(dbList);
|
return _mapper.Map<List<VariableHistory>>(dbList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据变量ID获取历史记录,支持条数限制和时间范围筛选
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>变量历史记录列表</returns>
|
||||||
|
public async Task<List<VariableHistory>> GetByVariableIdAsync(int variableId, int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
|
{
|
||||||
|
var query = Db.Queryable<DbVariableHistory>()
|
||||||
|
.Where(h => h.VariableId == variableId);
|
||||||
|
|
||||||
|
// 添加时间范围筛选
|
||||||
|
if (startTime.HasValue)
|
||||||
|
query = query.Where(h => h.Timestamp >= startTime.Value);
|
||||||
|
|
||||||
|
if (endTime.HasValue)
|
||||||
|
query = query.Where(h => h.Timestamp <= endTime.Value);
|
||||||
|
|
||||||
|
// 按时间倒序排列
|
||||||
|
query = query.OrderBy(h => h.Timestamp, SqlSugar.OrderByType.Desc);
|
||||||
|
|
||||||
|
// 添加条数限制
|
||||||
|
if (limit.HasValue)
|
||||||
|
query = query.Take(limit.Value);
|
||||||
|
|
||||||
|
var dbList = await query.ToListAsync();
|
||||||
|
return _mapper.Map<List<VariableHistory>>(dbList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取所有历史记录,支持条数限制和时间范围筛选
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
/// <returns>所有历史记录列表</returns>
|
||||||
|
public new async Task<List<VariableHistory>> GetAllAsync(int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
|
{
|
||||||
|
var query = Db.Queryable<DbVariableHistory>();
|
||||||
|
|
||||||
|
// 添加时间范围筛选
|
||||||
|
if (startTime.HasValue)
|
||||||
|
query = query.Where(h => h.Timestamp >= startTime.Value);
|
||||||
|
|
||||||
|
if (endTime.HasValue)
|
||||||
|
query = query.Where(h => h.Timestamp <= endTime.Value);
|
||||||
|
|
||||||
|
// 按时间倒序排列
|
||||||
|
query = query.OrderBy(h => h.Timestamp, SqlSugar.OrderByType.Desc);
|
||||||
|
|
||||||
|
// 添加条数限制
|
||||||
|
if (limit.HasValue)
|
||||||
|
query = query.Take(limit.Value);
|
||||||
|
|
||||||
|
var dbList = await query.ToListAsync();
|
||||||
|
return _mapper.Map<List<VariableHistory>>(dbList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -216,6 +216,7 @@ public partial class App : System.Windows.Application
|
|||||||
services.AddSingleton<IInitializeService, InitializeService>();
|
services.AddSingleton<IInitializeService, InitializeService>();
|
||||||
services.AddSingleton<IDeviceAppService, DeviceAppService>();
|
services.AddSingleton<IDeviceAppService, DeviceAppService>();
|
||||||
services.AddSingleton<IVariableAppService, VariableAppService>();
|
services.AddSingleton<IVariableAppService, VariableAppService>();
|
||||||
|
services.AddSingleton<IHistoryAppService, HistoryAppService>();
|
||||||
services.AddSingleton<IVariableTableAppService, VariableTableAppService>();
|
services.AddSingleton<IVariableTableAppService, VariableTableAppService>();
|
||||||
services.AddSingleton<IMenuService, MenuService>();
|
services.AddSingleton<IMenuService, MenuService>();
|
||||||
services.AddSingleton<IAppDataCenterService, AppDataCenterService>();
|
services.AddSingleton<IAppDataCenterService, AppDataCenterService>();
|
||||||
|
|||||||
@@ -9,36 +9,19 @@ using DMS.WPF.Interfaces;
|
|||||||
using DMS.WPF.ViewModels.Items;
|
using DMS.WPF.ViewModels.Items;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using ObservableCollections;
|
using ObservableCollections;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace DMS.WPF.ViewModels;
|
namespace DMS.WPF.ViewModels;
|
||||||
|
|
||||||
partial class VariableHistoryViewModel : ViewModelBase,INavigatable
|
partial class VariableHistoryViewModel : ViewModelBase, INavigatable
|
||||||
{
|
{
|
||||||
private readonly IMapper _mapper;
|
private readonly IMapper _mapper;
|
||||||
private readonly IDialogService _dialogService;
|
private readonly IDialogService _dialogService;
|
||||||
private readonly IVariableAppService _variableAppService;
|
private readonly IHistoryAppService _historyAppService;
|
||||||
private readonly IWPFDataService _wpfDataService;
|
private readonly IWPFDataService _wpfDataService;
|
||||||
private readonly IDataStorageService _dataStorageService;
|
private readonly IDataStorageService _dataStorageService;
|
||||||
private readonly INotificationService _notificationService;
|
private readonly INotificationService _notificationService;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前选中的设备
|
|
||||||
/// </summary>
|
|
||||||
[ObservableProperty]
|
|
||||||
private DeviceItemViewModel _selectedDevice;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前选中的变量表
|
|
||||||
/// </summary>
|
|
||||||
[ObservableProperty]
|
|
||||||
private VariableTableItemViewModel _selectedVariableTable;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当前选中的变量
|
|
||||||
/// </summary>
|
|
||||||
[ObservableProperty]
|
|
||||||
private VariableItemViewModel _selectedVariable;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于过滤变量的搜索文本
|
/// 用于过滤变量的搜索文本
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -46,142 +29,87 @@ partial class VariableHistoryViewModel : ViewModelBase,INavigatable
|
|||||||
private string _searchText;
|
private string _searchText;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 所有设备列表
|
/// 是否打开建议列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotifyCollectionChangedSynchronizedViewList<DeviceItemViewModel> Devices { get; }
|
[ObservableProperty]
|
||||||
|
private bool _isSuggestionListOpen;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前设备下的变量表列表
|
/// 建议的变量列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotifyCollectionChangedSynchronizedViewList<VariableTableItemViewModel> VariableTables { get; }
|
[ObservableProperty]
|
||||||
|
private List<VariableHistoryDto> _suggestedVariables;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当前变量表下的变量列表
|
/// 历史记录条数限制
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotifyCollectionChangedSynchronizedViewList<VariableItemViewModel> Variables { get; }
|
[ObservableProperty]
|
||||||
|
private int? _historyLimit;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 历史记录开始时间
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private DateTime? _startTime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 历史记录结束时间
|
||||||
|
/// </summary>
|
||||||
|
[ObservableProperty]
|
||||||
|
private DateTime? _endTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 变量历史记录列表
|
/// 变量历史记录列表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public NotifyCollectionChangedSynchronizedViewList<VariableHistoryDto> VariableHistories { get; }
|
public NotifyCollectionChangedSynchronizedViewList<VariableHistoryDto> VariableHistories { get; }
|
||||||
|
|
||||||
private readonly ObservableList<DeviceItemViewModel> _deviceItemList;
|
|
||||||
private readonly ObservableList<VariableTableItemViewModel> _variableTableItemList;
|
|
||||||
private readonly ObservableList<VariableItemViewModel> _variableItemList;
|
|
||||||
private readonly ObservableList<VariableHistoryDto> _variableHistoryList;
|
private readonly ObservableList<VariableHistoryDto> _variableHistoryList;
|
||||||
|
|
||||||
private readonly ISynchronizedView<DeviceItemViewModel, DeviceItemViewModel> _deviceSynchronizedView;
|
|
||||||
private readonly ISynchronizedView<VariableTableItemViewModel, VariableTableItemViewModel> _variableTableSynchronizedView;
|
|
||||||
private readonly ISynchronizedView<VariableItemViewModel, VariableItemViewModel> _variableSynchronizedView;
|
|
||||||
private readonly ISynchronizedView<VariableHistoryDto, VariableHistoryDto> _variableHistorySynchronizedView;
|
private readonly ISynchronizedView<VariableHistoryDto, VariableHistoryDto> _variableHistorySynchronizedView;
|
||||||
|
|
||||||
public VariableHistoryViewModel(IMapper mapper, IDialogService dialogService, IVariableAppService variableAppService,
|
/// <summary>
|
||||||
|
/// 所有变量的缓存列表,用于搜索
|
||||||
|
/// </summary>
|
||||||
|
private List<VariableHistoryDto> _allVariableHistories;
|
||||||
|
|
||||||
|
public VariableHistoryViewModel(IMapper mapper, IDialogService dialogService, IHistoryAppService historyAppService,
|
||||||
IWPFDataService wpfDataService, IDataStorageService dataStorageService, INotificationService notificationService)
|
IWPFDataService wpfDataService, IDataStorageService dataStorageService, INotificationService notificationService)
|
||||||
{
|
{
|
||||||
_mapper = mapper;
|
_mapper = mapper;
|
||||||
_dialogService = dialogService;
|
_dialogService = dialogService;
|
||||||
_variableAppService = variableAppService;
|
_historyAppService = historyAppService;
|
||||||
_wpfDataService = wpfDataService;
|
_wpfDataService = wpfDataService;
|
||||||
_dataStorageService = dataStorageService;
|
_dataStorageService = dataStorageService;
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
|
|
||||||
_deviceItemList = new ObservableList<DeviceItemViewModel>();
|
|
||||||
_variableTableItemList = new ObservableList<VariableTableItemViewModel>();
|
|
||||||
_variableItemList = new ObservableList<VariableItemViewModel>();
|
|
||||||
_variableHistoryList = new ObservableList<VariableHistoryDto>();
|
_variableHistoryList = new ObservableList<VariableHistoryDto>();
|
||||||
|
|
||||||
_deviceSynchronizedView = _deviceItemList.CreateView(v => v);
|
|
||||||
_variableTableSynchronizedView = _variableTableItemList.CreateView(v => v);
|
|
||||||
_variableSynchronizedView = _variableItemList.CreateView(v => v);
|
|
||||||
_variableHistorySynchronizedView = _variableHistoryList.CreateView(v => v);
|
_variableHistorySynchronizedView = _variableHistoryList.CreateView(v => v);
|
||||||
|
|
||||||
Devices = _deviceSynchronizedView.ToNotifyCollectionChanged();
|
|
||||||
VariableTables = _variableTableSynchronizedView.ToNotifyCollectionChanged();
|
|
||||||
Variables = _variableSynchronizedView.ToNotifyCollectionChanged();
|
|
||||||
VariableHistories = _variableHistorySynchronizedView.ToNotifyCollectionChanged();
|
VariableHistories = _variableHistorySynchronizedView.ToNotifyCollectionChanged();
|
||||||
}
|
_allVariableHistories = new List<VariableHistoryDto>();
|
||||||
|
_suggestedVariables = new List<VariableHistoryDto>();
|
||||||
|
|
||||||
|
// 初始化默认值
|
||||||
/// <summary>
|
_historyLimit = 1000; // 默认限制1000条记录
|
||||||
/// 加载所有设备
|
_startTime = null;
|
||||||
/// </summary>
|
_endTime = null;
|
||||||
private void LoadDevices()
|
|
||||||
{
|
|
||||||
_deviceItemList.Clear();
|
|
||||||
_deviceItemList.AddRange(_dataStorageService.Devices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 当选中的设备发生变化时
|
/// 加载所有变量的历史记录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value"></param>
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
partial void OnSelectedDeviceChanged(DeviceItemViewModel value)
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
{
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
if (value != null)
|
private async void LoadAllVariableHistories(int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
{
|
|
||||||
// 清空变量表和变量列表
|
|
||||||
_variableTableItemList.Clear();
|
|
||||||
_variableItemList.Clear();
|
|
||||||
_variableHistoryList.Clear();
|
|
||||||
|
|
||||||
// 加载选中设备下的变量表
|
|
||||||
_variableTableItemList.AddRange(value.VariableTables);
|
|
||||||
|
|
||||||
// 清空选中项
|
|
||||||
SelectedVariableTable = null;
|
|
||||||
SelectedVariable = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当选中的变量表发生变化时
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
partial void OnSelectedVariableTableChanged(VariableTableItemViewModel value)
|
|
||||||
{
|
|
||||||
if (value != null)
|
|
||||||
{
|
|
||||||
// 清空变量列表和历史记录
|
|
||||||
_variableItemList.Clear();
|
|
||||||
_variableHistoryList.Clear();
|
|
||||||
|
|
||||||
// 加载选中变量表下的变量
|
|
||||||
_variableItemList.AddRange(value.Variables);
|
|
||||||
|
|
||||||
// 清空选中项
|
|
||||||
SelectedVariable = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 当选中的变量发生变化时
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="value"></param>
|
|
||||||
partial void OnSelectedVariableChanged(VariableItemViewModel value)
|
|
||||||
{
|
|
||||||
// if (value != null)
|
|
||||||
// {
|
|
||||||
// // 加载选中变量的历史记录
|
|
||||||
// LoadVariableHistories(value.Id);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// _variableHistoryList.Clear();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加载变量的历史记录
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="variableId"></param>
|
|
||||||
private async void LoadVariableHistories(int variableId)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_variableHistoryList.Clear();
|
_variableHistoryList.Clear();
|
||||||
var histories = await _variableAppService.GetVariableHistoriesAsync(variableId);
|
var allHistories = await _historyAppService.GetAllVariableHistoriesAsync(limit, startTime, endTime);
|
||||||
_variableHistoryList.AddRange(histories);
|
_allVariableHistories = allHistories.ToList();
|
||||||
|
_variableHistoryList.AddRange(_allVariableHistories);
|
||||||
|
|
||||||
|
// 更新建议列表
|
||||||
|
UpdateSuggestedVariables();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -191,49 +119,99 @@ partial class VariableHistoryViewModel : ViewModelBase,INavigatable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 搜索变量
|
/// 更新建议的变量列表
|
||||||
|
/// </summary>
|
||||||
|
private void UpdateSuggestedVariables()
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(SearchText))
|
||||||
|
{
|
||||||
|
// 如果搜索文本为空,显示所有唯一的变量名
|
||||||
|
_suggestedVariables = _allVariableHistories
|
||||||
|
.GroupBy(h => h.VariableName)
|
||||||
|
.Select(g => g.First())
|
||||||
|
.Take(10)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 根据搜索文本过滤建议列表
|
||||||
|
_suggestedVariables = _allVariableHistories
|
||||||
|
.Where(h =>
|
||||||
|
h.VariableName?.Contains(SearchText, StringComparison.OrdinalIgnoreCase) ==
|
||||||
|
true)
|
||||||
|
.GroupBy(h => h.VariableName)
|
||||||
|
.Select(g => g.First())
|
||||||
|
.Take(10)
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 搜索变量历史记录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="value"></param>
|
/// <param name="value"></param>
|
||||||
partial void OnSearchTextChanged(string value)
|
partial void OnSearchTextChanged(string value)
|
||||||
{
|
{
|
||||||
if (SelectedVariableTable == null) return;
|
// 更新建议列表
|
||||||
|
UpdateSuggestedVariables();
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(SearchText))
|
if (string.IsNullOrWhiteSpace(SearchText))
|
||||||
{
|
{
|
||||||
_variableSynchronizedView.ResetFilter();
|
// 如果搜索文本为空,显示所有历史记录
|
||||||
|
_variableHistoryList.Clear();
|
||||||
|
_variableHistoryList.AddRange(_allVariableHistories);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_variableSynchronizedView.AttachFilter(FilterVariables);
|
// 根据搜索文本过滤历史记录
|
||||||
}
|
var filteredHistories = _allVariableHistories
|
||||||
}
|
.Where(h =>
|
||||||
|
h.VariableName?.Contains(
|
||||||
|
SearchText, StringComparison.OrdinalIgnoreCase) == true)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
/// <summary>
|
_variableHistoryList.Clear();
|
||||||
/// 过滤变量
|
_variableHistoryList.AddRange(filteredHistories);
|
||||||
/// </summary>
|
}
|
||||||
/// <param name="item"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private bool FilterVariables(VariableItemViewModel item)
|
|
||||||
{
|
|
||||||
var searchTextLower = SearchText.ToLower();
|
|
||||||
return item.Name?.ToLower().Contains(searchTextLower) == true ||
|
|
||||||
item.Description?.ToLower().Contains(searchTextLower) == true ||
|
|
||||||
item.OpcUaNodeId?.ToLower().Contains(searchTextLower) == true ||
|
|
||||||
item.S7Address?.ToLower().Contains(searchTextLower) == true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task OnNavigatedToAsync(MenuItemViewModel menu)
|
public async Task OnNavigatedToAsync(MenuItemViewModel menu)
|
||||||
{
|
{
|
||||||
|
// 加载所有变量的历史记录
|
||||||
VariableItemViewModel variable =_dataStorageService.Variables.FirstOrDefault(v => v.Id == menu.TargetId);
|
LoadAllVariableHistories(HistoryLimit, StartTime, EndTime);
|
||||||
if (variable!=null)
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重新加载历史记录,使用当前设置的限制和时间范围
|
||||||
|
/// </summary>
|
||||||
|
public void ReloadHistories()
|
||||||
|
{
|
||||||
|
LoadAllVariableHistories(HistoryLimit, StartTime, EndTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 根据变量ID加载历史记录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="variableId">变量ID</param>
|
||||||
|
/// <param name="limit">返回记录的最大数量,null表示无限制</param>
|
||||||
|
/// <param name="startTime">开始时间,null表示无限制</param>
|
||||||
|
/// <param name="endTime">结束时间,null表示无限制</param>
|
||||||
|
public async Task LoadVariableHistoriesAsync(int variableId, int? limit = null, DateTime? startTime = null, DateTime? endTime = null)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// 直接设置选中的变量
|
_variableHistoryList.Clear();
|
||||||
SelectedVariable = variable;
|
var histories = await _historyAppService.GetVariableHistoriesAsync(variableId, limit, startTime, endTime);
|
||||||
|
_variableHistoryList.AddRange(histories);
|
||||||
|
|
||||||
// 加载历史记录
|
// 更新建议列表
|
||||||
LoadVariableHistories(variable.Id);
|
UpdateSuggestedVariables();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// 记录更详细的错误信息
|
||||||
|
_notificationService.ShowError($"加载变量历史记录失败: {ex.Message}", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,41 +39,22 @@
|
|||||||
|
|
||||||
<DockPanel>
|
<DockPanel>
|
||||||
<ikw:SimpleStackPanel Margin="10" DockPanel.Dock="Top">
|
<ikw:SimpleStackPanel Margin="10" DockPanel.Dock="Top">
|
||||||
<!-- 选择区域 -->
|
<!-- 搜索区域 -->
|
||||||
<GroupBox Header="选择条件">
|
<GroupBox Header="搜索条件">
|
||||||
<ikw:SimpleStackPanel Margin="5" Spacing="10">
|
<ikw:SimpleStackPanel Margin="5" Spacing="10">
|
||||||
<ikw:SimpleStackPanel Orientation="Horizontal" Spacing="10">
|
|
||||||
<TextBlock Style="{StaticResource VarHistoryLabelStyle}" Text="设备:" />
|
|
||||||
<ComboBox
|
|
||||||
MinWidth="150"
|
|
||||||
DisplayMemberPath="Name"
|
|
||||||
ItemsSource="{Binding Devices}"
|
|
||||||
SelectedItem="{Binding SelectedDevice}" />
|
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource VarHistoryLabelStyle}" Text="变量表:" />
|
|
||||||
<ComboBox
|
|
||||||
MinWidth="150"
|
|
||||||
DisplayMemberPath="Name"
|
|
||||||
ItemsSource="{Binding VariableTables}"
|
|
||||||
SelectedItem="{Binding SelectedVariableTable}" />
|
|
||||||
|
|
||||||
<TextBlock Style="{StaticResource VarHistoryLabelStyle}" Text="变量:" />
|
|
||||||
<ComboBox
|
|
||||||
MinWidth="150"
|
|
||||||
DisplayMemberPath="Name"
|
|
||||||
ItemsSource="{Binding Variables}"
|
|
||||||
SelectedItem="{Binding SelectedVariable}" />
|
|
||||||
</ikw:SimpleStackPanel>
|
|
||||||
|
|
||||||
<ikw:SimpleStackPanel
|
<ikw:SimpleStackPanel
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Left"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Spacing="10">
|
Spacing="10">
|
||||||
<TextBlock Style="{StaticResource VarHistoryLabelStyle}" Text="搜索变量:" />
|
<TextBlock Style="{StaticResource VarHistoryLabelStyle}" Text="搜索变量:" />
|
||||||
<TextBox
|
<ui:AutoSuggestBox
|
||||||
Width="200"
|
Width="200"
|
||||||
ui:ControlHelper.PlaceholderText="搜索变量..."
|
ui:ControlHelper.PlaceholderText="搜索变量..."
|
||||||
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
|
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
ItemsSource="{Binding SuggestedVariables}"
|
||||||
|
DisplayMemberPath="VariableName"
|
||||||
|
IsSuggestionListOpen="{Binding IsSuggestionListOpen, Mode=TwoWay}"
|
||||||
|
TextMemberPath="VariableName" />
|
||||||
</ikw:SimpleStackPanel>
|
</ikw:SimpleStackPanel>
|
||||||
</ikw:SimpleStackPanel>
|
</ikw:SimpleStackPanel>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
@@ -89,6 +70,7 @@
|
|||||||
SelectionMode="Single"
|
SelectionMode="Single"
|
||||||
Style="{StaticResource DataGridBaseStyle}">
|
Style="{StaticResource DataGridBaseStyle}">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
|
<DataGridTextColumn Binding="{Binding VariableName}" Header="变量名" />
|
||||||
<DataGridTextColumn Binding="{Binding Value}" Header="值" />
|
<DataGridTextColumn Binding="{Binding Value}" Header="值" />
|
||||||
<DataGridTextColumn
|
<DataGridTextColumn
|
||||||
Binding="{Binding Timestamp, StringFormat='{}{0:yyyy-MM-dd HH:mm:ss.fff}'}"
|
Binding="{Binding Timestamp, StringFormat='{}{0:yyyy-MM-dd HH:mm:ss.fff}'}"
|
||||||
|
|||||||
Reference in New Issue
Block a user