using FATrace.WPLApp.Core; using Prism.Commands; using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using FreeSql; using FATrace.Model; using FATrace.WPLApp.Services; using System.Windows; using System.Linq; namespace FATrace.WPLApp.ViewModels { /// /// 历史报警查询 VM /// 支持按时间范围/类别/消息模糊查询,分页展示。 /// public class HistoryAlarmViewModel : NavigationViewModel { private readonly IFreeSql _fsql; private readonly ILogService _log; public HistoryAlarmViewModel(IFreeSql fsql, ILogService log) { _fsql = fsql; _log = log; Items = new ObservableCollection(); CategoryList = new ObservableCollection(); // 默认时间范围为今日 StartTime = DateTime.Today; EndTime = DateTime.Today.AddDays(1).AddSeconds(-1); SearchCommand = new DelegateCommand(async () => await SearchAsync(), () => !IsBusy) .ObservesProperty(() => IsBusy); ClearCommand = new DelegateCommand(ClearFilters, () => !IsBusy) .ObservesProperty(() => IsBusy); FirstPageCommand = new DelegateCommand(async () => { if (PageIndex == 1) return; PageIndex = 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1) .ObservesProperty(() => IsBusy).ObservesProperty(() => PageIndex); PrevPageCommand = new DelegateCommand(async () => { if (PageIndex <= 1) return; PageIndex -= 1; await SearchAsync(); }, () => !IsBusy && PageIndex > 1) .ObservesProperty(() => IsBusy).ObservesProperty(() => PageIndex); NextPageCommand = new DelegateCommand(async () => { if (PageIndex >= TotalPages) return; PageIndex += 1; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages) .ObservesProperty(() => IsBusy).ObservesProperty(() => PageIndex).ObservesProperty(() => TotalPages); LastPageCommand = new DelegateCommand(async () => { if (TotalPages <= 0 || PageIndex == TotalPages) return; PageIndex = TotalPages; await SearchAsync(); }, () => !IsBusy && PageIndex < TotalPages) .ObservesProperty(() => IsBusy).ObservesProperty(() => PageIndex).ObservesProperty(() => TotalPages); } #region 查询条件 public string? Category { get => _category; set { _category = value; RaisePropertyChanged(); } } private string? _category; public ObservableCollection CategoryList { get; } public string? Keyword { get => _keyword; set { _keyword = value; RaisePropertyChanged(); } } private string? _keyword; public DateTime? StartTime { get => _startTime; set { _startTime = value; RaisePropertyChanged(); } } private DateTime? _startTime; public DateTime? EndTime { get => _endTime; set { _endTime = value; RaisePropertyChanged(); } } private DateTime? _endTime; #endregion #region 列表/状态/分页 public ObservableCollection Items { get; } private bool _isBusy; public bool IsBusy { get => _isBusy; set { _isBusy = value; RaisePropertyChanged(); } } private int _totalCount; public int TotalCount { get => _totalCount; set { _totalCount = value; RaisePropertyChanged(); } } private int _pageIndex = 1; public int PageIndex { get => _pageIndex; set { _pageIndex = value < 1 ? 1 : value; RaisePropertyChanged(); } } private int _pageSize = 20; public int PageSize { get => _pageSize; set { var newSize = value <= 0 ? 20 : value; if (_pageSize != newSize) { _pageSize = newSize; RaisePropertyChanged(); PageIndex = 1; if (!IsBusy) _ = SearchAsync(); } } } private int _totalPages; public int TotalPages { get => _totalPages; set { _totalPages = value; RaisePropertyChanged(); } } #endregion #region 命令 public DelegateCommand SearchCommand { get; } public DelegateCommand ClearCommand { get; } public DelegateCommand FirstPageCommand { get; } public DelegateCommand PrevPageCommand { get; } public DelegateCommand NextPageCommand { get; } public DelegateCommand LastPageCommand { get; } #endregion private void ClearFilters() { Category = "全部"; Keyword = string.Empty; StartTime = DateTime.Today; EndTime = DateTime.Today.AddDays(1).AddSeconds(-1); } private async Task SearchAsync() { if (IsBusy) return; try { if (StartTime.HasValue && EndTime.HasValue && StartTime > EndTime) { MessageBox.Show("开始时间不能大于结束时间", "提示", MessageBoxButton.OK, MessageBoxImage.Warning); return; } IsBusy = true; _log.Info("HistoryAlarm 查询开始"); var data = await Task.Run(() => { var q = _fsql.Select(); DateTime? start = StartTime; DateTime? end = EndTime; if (start.HasValue) q = q.Where(a => a.CreateTime >= start.Value); if (end.HasValue) { var endInclusive = end.Value; if (endInclusive.TimeOfDay == TimeSpan.Zero) endInclusive = endInclusive.Date.AddDays(1).AddTicks(-1); q = q.Where(a => a.CreateTime <= endInclusive); } if (!string.IsNullOrWhiteSpace(Category) && Category != "全部") q = q.Where(a => a.Category == Category); if (!string.IsNullOrWhiteSpace(Keyword)) q = q.Where(a => a.Message!.Contains(Keyword)); q = q.OrderByDescending(a => a.CreateTime); var size = PageSize <= 0 ? 20 : PageSize; var page = PageIndex < 1 ? 1 : PageIndex; var list = q.Count(out var total) .Page(page, size) .ToList(); var pages = total <= 0 || size <= 0 ? 0 : (int)Math.Ceiling(total * 1.0 / size); if (pages > 0 && page > pages) { page = pages; list = q.Page(page, size).ToList(); } return (items: list, total: (int)total, normalizedPage: page, totalPages: pages); }); Application.Current.Dispatcher.Invoke(() => { Items.Clear(); foreach (var it in data.items) Items.Add(it); TotalCount = data.total; TotalPages = data.totalPages; PageIndex = data.normalizedPage == 0 ? 1 : data.normalizedPage; }); _log.Info($"HistoryAlarm 查询完成,记录数: {TotalCount}"); } catch (Exception ex) { _log.Error($"HistoryAlarm 查询失败: {ex}"); MessageBox.Show($"查询失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } finally { IsBusy = false; } } public override async void OnNavigatedTo(Prism.Regions.NavigationContext navigationContext) { await LoadCategoriesAsync(); await SearchAsync(); } private async Task LoadCategoriesAsync() { try { var list = await Task.Run(() => { // 直接在数据库端去重,避免将大量重复数据拉回内存 var cateList = _fsql.Select() .Where(a => a.Category != null && a.Category != "") .Distinct() .ToList(a => a.Category); return (cateList ?? new System.Collections.Generic.List()) .Where(s => !string.IsNullOrWhiteSpace(s)) .OrderBy(s => s) .ToList(); }); Application.Current.Dispatcher.Invoke(() => { CategoryList.Clear(); CategoryList.Add("全部"); foreach (var s in list) CategoryList.Add(s); if (string.IsNullOrWhiteSpace(Category)) Category = "全部"; }); } catch (Exception ex) { _log.Warn($"加载报警类别失败: {ex.Message}"); Application.Current.Dispatcher.Invoke(() => { if (CategoryList.Count == 0) CategoryList.Add("全部"); if (string.IsNullOrWhiteSpace(Category)) Category = "全部"; }); } } } }