Sic.Framework-Nanjing-Baishi/MECF.Framework.UI.Client/CenterViews/Maintain/ViewModels/MaintainEventViewModel.cs

839 lines
27 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Aitex.Core.RT.Event;
using Aitex.Core.Util;
using Caliburn.Micro;
using DocumentFormat.OpenXml.Drawing;
using MECF.Framework.Common.Aitex.Core.RT.EMS;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.OperationCenter;
using MECF.Framework.UI.Client.CenterViews.DataLogs.Event;
using MECF.Framework.UI.Client.ClientBase;
using OpenSEMI.ClientBase;
using OpenSEMI.ClientBase.Command;
using SciChart.Core.Extensions;
using Sicentury.Core.Collections;
namespace MECF.Framework.UI.Client.CenterViews.Maintain.ViewModels
{
public class MaintainEventViewModel : UiViewModelBase, ISupportMultipleSystem
{
#region Properties
MaintainEventView view;
public ICommand NavigateCommand { get; set; }
/// <summary>
/// 搜索条件:开始时间
/// </summary>
public DateTime SearchBeginTime
{
get => view.wfTimeFrom.Value;
set
{
view.wfTimeFrom.Value = value;
NotifyOfPropertyChange(nameof(SearchBeginTime));
}
}
/// <summary>
/// 搜索条件:结束时间
/// </summary>
public DateTime SearchEndTime
{
get => view.wfTimeTo.Value;
set
{
view.wfTimeTo.Value = value;
NotifyOfPropertyChange(nameof(SearchEndTime));
}
}
private List<string> _plannames = new();
/// <summary>
/// 复选框选项:PlanNamesList不会更新
/// </summary>
public List<string> PlanNames
{
get { return _plannames; }
set
{
_plannames = value;
NotifyOfPropertyChange(nameof(PlanNames));
}
}
private ObservableCollection<string> _planmodules = new();
/// <summary>
/// 复选框选项:PlanModules随着planname更新
/// </summary>
public ObservableCollection<string> PlanModules
{
get { return _planmodules; }
set
{
_planmodules = value;
NotifyOfPropertyChange(nameof(PlanModules));
}
}
private Dictionary<string,List<string>> planmoduledic = new Dictionary<string,List<string>>();
private string _searchplanname = "";
/// <summary>
/// 搜索条件:Plan
/// </summary>
public string SearchPlanName
{
get { return _searchplanname; }
set
{
if (_searchplanname != value)
{
_searchplanname = value;
NotifyOfPropertyChange(nameof(SearchPlanName));
SearchPlanModule = "";
PlanModules.Clear();
if (planmoduledic.Keys.Contains(value))
{
planmoduledic[value].ForEach(PlanModules.Add);
}
}
}
}
private string _searchplanmodule = "";
/// <summary>
/// 搜索条件:Module
/// </summary>
public string SearchPlanModule
{
get { return _searchplanmodule; }
set
{
_searchplanmodule = value;
NotifyOfPropertyChange(nameof(SearchPlanModule));
}
}
private List<MaintainerItemConfigInfo> items = new();
private List<string> _parentitemnames = new();
/// <summary>
/// 复选框选项:ParentItemNamesList不会更新
/// </summary>
public List<string> ParentItemNames
{
get { return _parentitemnames; }
set
{
_parentitemnames = value;
NotifyOfPropertyChange(nameof(ParentItemNames));
}
}
private ObservableCollection<string> _itemnames = new();
/// <summary>
/// 复选框选项:ParentItemNames随着ParentItemName更新
/// </summary>
public ObservableCollection<string> ItemNames
{
get { return _itemnames; }
set
{
_itemnames = value;
NotifyOfPropertyChange(nameof(ItemNames));
}
}
private ObservableCollection<string> _itemindexs = new() {"" };
/// <summary>
/// 复选框选项:ParentItemNames随着ParentItemName更新
/// </summary>
public ObservableCollection<string> ItemIndexs
{
get { return _itemindexs; }
set
{
_itemindexs = value;
NotifyOfPropertyChange(nameof(ItemIndexs));
}
}
private string _searchparentitemname="";
/// <summary>
/// 搜索条件:ParentItem
/// </summary>
public string SearchParentItemName
{
get { return _searchparentitemname; }
set
{
if (_searchparentitemname != value)
{
_searchparentitemname = value;
NotifyOfPropertyChange(nameof(SearchParentItemName));
ItemNames.Clear();
ItemIndexs.Clear();
ItemNames.Add("");
ItemIndexs.Add("");
items.ForEach(i =>
{
if (i.ParentName == _searchparentitemname)
{
if (!ItemNames.Contains(i.Name))
{
ItemNames.Add(i.Name);
}
}
});
SearchItemName = "";
SearchIndex = "";
}
}
}
private string _searchitemname = "";
/// <summary>
/// 搜索条件:Item
/// </summary>
public string SearchItemName
{
get { return _searchitemname; }
set
{
if (_searchitemname != value)
{
_searchitemname = value;
NotifyOfPropertyChange(nameof(SearchItemName));
ItemIndexs.Clear();
ItemIndexs.Add("");
ItemIndexs.Add("0");
items.ForEach(i =>
{
if (i.ParentName == _searchparentitemname && i.Name == _searchitemname)
{
if (!ItemIndexs.Contains(i.Index.ToString()))
{
ItemIndexs.Add(i.Index.ToString());
}
}
});
SearchIndex = "";
}
}
}
private string _searchindex = "0";
/// <summary>
/// 搜索条件:Index
/// </summary>
public string SearchIndex
{
get { return _searchindex; }
set
{
_searchindex = value;
NotifyOfPropertyChange(nameof(SearchIndex));
}
}
private string _searchkeywords = "";
/// <summary>
/// 搜索条件:Index
/// </summary>
public string SearchKeyWords
{
get { return _searchkeywords; }
set
{
_searchkeywords = value;
NotifyOfPropertyChange(nameof(SearchKeyWords));
}
}
List<MaintainEventInfo> queryresult = new();
/// <summary>
/// 返回受支持的分页每页容量。
/// </summary>
public List<int> PaginationCapacity { get; }
private int _selectedPaginationCapacity;
/// <summary>
/// 返回选择的分页每页容量。
/// </summary>
public int SelectedPaginationCapacity
{
get => _selectedPaginationCapacity;
set
{
_selectedPaginationCapacity = value;
Query();
}
}
/// <summary>
/// 更新分页信息。
/// <para>Tuple.Item1: 当前页号</para>
/// <para>Tuple.Item2: 总页号;设置为-1时表示忽略更新总页号。</para>
/// </summary>
private readonly IProgress<Tuple<int, int>> _progUpdatePaginationInfo;
/// <summary>
/// 更新查询状态。
/// </summary>
private readonly IProgress<bool> _progUpdateQueryStatus;
public ObservableRangeCollection<MaintainEventInfo> SearchedResult { get; private set; }
/// <summary>
/// 显示查询到的事件日志列表。
/// </summary>
private readonly IProgress<List<MaintainEventInfo>> _progShowSearchingResult;
private List<MaintainEventInfo> _alleventinfos = new();
public List<MaintainEventInfo> AllEvenInfos
{
get { return _alleventinfos; }
set
{
_alleventinfos = value;
NotifyOfPropertyChange(nameof(AllEvenInfos));
}
}
private bool _isLoading;
/// <summary>
/// 返回是否正在加载数据。
/// </summary>
public bool IsLoading
{
get => _isLoading;
set
{
_isLoading = value;
NotifyOfPropertyChange(nameof(IsLoading));
}
}
/// <summary>
/// 页码列表,用于快速跳转页面下拉框数据源。
/// </summary>
public ObservableRangeCollection<int> PaginationSource { get; }
/// <summary>
/// 页码信息。
/// </summary>
public string PageInfo => $"{_currentPage}/{_totalPage}";
private int _currentPage;
private int _totalPage;
private int _selectedPage;
public int SelectedPage
{
get => _selectedPage;
set
{
_selectedPage = value;
Query(_selectedPage);
}
}
#endregion
#region Constructors
public MaintainEventViewModel()
{
DisplayName = "MaintainEvent";
SearchedResult = new ObservableRangeCollection<MaintainEventInfo>();
PaginationSource = new ObservableRangeCollection<int>();
NavigateCommand = new BaseCommand<string>(Navigate, (o) => true);
// 分页支持的每页Log数量
//! 最小每页条目数使用30以保证正好显示一页而不出现纵向滚动条。
PaginationCapacity = new List<int>
{
30,
300,
3000
};
_selectedPaginationCapacity = PaginationCapacity.Last();
_totalPage = 1;
_currentPage = 1;
#region plan搜索条件信息
List<MaintainerInfo> maintainerlist = (List<MaintainerInfo>)QueryDataClient.Instance.Service.GetData("MaintainManager.MaintainerInfos");
PlanNames.Add("");
planmoduledic.Add("", new List<string>() { "" });
foreach (MaintainerInfo item in maintainerlist)
{
PlanNames.AddIfNotContains(item.Name);
if (!planmoduledic.ContainsKey(item.Name))
{
planmoduledic.Add(item.Name, new List<string>() { "" });
}
planmoduledic[item.Name].AddIfNotContains(item.Module);
}
#endregion
#region item搜索条件信息
items = (List<MaintainerItemConfigInfo>)QueryDataClient.Instance.Service.GetData("MaintainManager.MaintainerConfigItems");
ParentItemNames = new List<string>() { "" };
ItemNames = new ObservableCollection<string>() { "" };
ItemIndexs = new ObservableCollection<string> { "0" };
items.ForEach(i =>
{
ParentItemNames.AddIfNotContains(i.ParentName);
});
#endregion
#region
_progShowSearchingResult = new Progress<List<MaintainEventInfo>>((queryRet =>
{
if (SearchedResult == null)
SearchedResult = new ObservableRangeCollection<MaintainEventInfo>();
else
SearchedResult.Clear();
queryRet.ForEach(i =>
{
foreach (var item in items)
{
if (item.ParentName == i.ParentItemName && item.Name == i.ItemName && item.Index == i.Index)
{
i.Description = item.Description;
break;
}
}
});
queryresult = queryRet;
SearchedResult.AddRange(queryRet);
}));
#endregion
#region
_progUpdatePaginationInfo = new Progress<Tuple<int, int>>(pageInfo =>
{
_currentPage = pageInfo.Item1;
if (pageInfo.Item2 > 0)
{
_totalPage = pageInfo.Item2;
PaginationSource.Clear();
PaginationSource.AddRange(Enumerable.Range(1, _totalPage));
NotifyOfPropertyChange(nameof(PaginationSource));
}
NotifyOfPropertyChange(nameof(PageInfo));
_selectedPage = _currentPage;
NotifyOfPropertyChange(nameof(SelectedPage));
});
#endregion
#region
_progUpdateQueryStatus = new Progress<bool>(isBusy =>
{
IsLoading = isBusy;
});
#endregion
}
#endregion
#region Functions
public void Navigate(string args)
{
switch (args)
{
case "first":
if (_currentPage == 1)
return;
_currentPage = 1;
break;
case "previous":
if (_currentPage > 1)
_currentPage--;
break;
case "next":
if (_currentPage < _totalPage)
_currentPage++;
break;
case "last":
if (_currentPage == _totalPage)
return;
_currentPage = _totalPage;
break;
default:
return;
}
Query(_currentPage);
}
protected override void OnInitialize()
{
ActiveUpdateData = false; //关闭界面后不开启后台线程,减少开销
}
protected override void OnViewLoaded(object view)
{
base.OnViewLoaded(view);
// 默认的查询时间设置为当天
this.view = (MaintainEventView)view;
SearchBeginTime = DateTime.Today.AddDays(-30);
SearchEndTime = DateTime.Today.AddDays(1).AddTicks(-1);
Preload();
}
private void Preload()
{
Query();
}
public void Filter()
{
SearchedResult.Clear();
var keywords = SearchKeyWords.ToLower();
queryresult.ForEach(i =>
{
if (i.PlanName.ToLower().Contains(keywords) ||
i.PlanModule.ToLower().Contains(keywords) ||
i.ParentItemName.ToLower().Contains(keywords) ||
i.ItemName.ToLower().Contains(keywords) ||
i.Description.ToLower().Contains(keywords) ||
i.Record.ToLower().Contains(keywords))
{
SearchedResult.Add(i);
}
});
}
/// <summary>
/// 查询数据。
/// </summary>
/// <param name="page">待查询的页号</param>
/// <param name="isIncludeFilter">是否包含过滤条件。</param>
/// <exception cref="ArgumentOutOfRangeException"></exception>
public void Query(int page = -1)
{
if (SearchBeginTime > SearchEndTime)
{
DialogBox.ShowError("Time range invalid, start time should be early than end time");
return;
}
Task.Run(() =>
{
var searchingResult = new List<MaintainEventInfo>();
// 查询开始
_progUpdateQueryStatus.Report(true);
if (page <= -1) // Query按钮按下或首次加载界面
{
// 统计总页数
var rowCount = QueryRowAmount(
SearchBeginTime,
SearchEndTime,
SearchPlanName,
SearchPlanModule,
SearchParentItemName,
SearchItemName,
SearchIndex == "" ? -1 : int.Parse(SearchIndex));
var totalPage = (int)Math.Ceiling(rowCount / (double)SelectedPaginationCapacity);
// 首次查询第一页
searchingResult = QueryEventLogs(
1,
SelectedPaginationCapacity,
SearchBeginTime,
SearchEndTime,
SearchPlanName,
SearchPlanModule,
SearchParentItemName,
SearchItemName,
SearchIndex == "" ? -1 : int.Parse(SearchIndex));
// 更新页面信息
_progUpdatePaginationInfo.Report(new Tuple<int, int>(1, totalPage));
}
else if (page >= 1)
{
// 翻页按钮按下
searchingResult = QueryEventLogs(
page,
SelectedPaginationCapacity,
SearchBeginTime,
SearchEndTime,
SearchPlanName,
SearchPlanModule,
SearchParentItemName,
SearchItemName,
SearchIndex == "" ? -1 : int.Parse(SearchIndex));
// 更新页面信息
_progUpdatePaginationInfo.Report(new Tuple<int, int>(page, -1));
}
else
{
throw new ArgumentOutOfRangeException(nameof(page), "invalid page number.");
}
// 显示结果
_progShowSearchingResult.Report(searchingResult);
// 查询完毕
_progUpdateQueryStatus.Report(false);
});
}
#endregion
#region
/// <summary>
/// 获取查询语句中select部分表达式。
/// </summary>
private string GetEventLogQuerySql(DateTime begintime, DateTime endtime)
{
return
"SELECT \"planname\", \"planmodule\", \"itemparentname\", \"itemname\", \"uid\",\"createtime\" , \"role\", \"detial\" FROM \"maintenance_event_data\"" +
GetWhereTimeRangeExpression(begintime, endtime);
}
/// <summary>
/// 获取EventLog行数查询语句中select部分表达式。
/// </summary>
private string GetEventCountSql(DateTime begintime, DateTime endtime)
{
return
"SELECT COUNT(1) FROM \"maintenance_event_data\"" + GetWhereTimeRangeExpression(begintime, endtime);
}
/// <summary>
/// 获取WHERE条件中的“时间范围”子句。
/// <para>注意所有Select语句构造时必须包含TimeRange条件。</para>
/// </summary>
/// <returns></returns>
private string GetWhereTimeRangeExpression(DateTime begintime, DateTime endtime)
{
var sql = new StringBuilder(
$" WHERE \"createtime\" BETWEEN '{begintime:yyyy/MM/dd HH:mm:ss}' AND '{endtime:yyyy/MM/dd HH:mm:ss}'");
return sql.ToString();
}
/// <summary>
/// 获取WHERE条件中的plan条件子句。
/// </summary>
/// <returns></returns>
private string GetWherePlanExpression(string planname = "", string module = "")
{
return ((planname == "") ? "" : $" AND \"planname\" = '{planname}'")
+ ((module == "") ? "" : $" AND \"planmodule\" = '{module}'");
}
/// <summary>
/// 获取WHERE条件中的item条件子句。
/// </summary>
/// <returns></returns>
private string GetWhereItemExpression(string itemparentname = "", string itemname = "", int index = -1)
{
return ((itemparentname == "") ? "" : $" AND \"itemparentname\" = '{itemparentname}'")
+ ((itemname == "") ? "" : $" AND \"itemname\" = '{itemname}'")
+ ((index == -1) ? "" : $"AND \"index\" = '{index}'");
}
/// <summary>
/// 获取WHERE条件中的“关键字”子句。
/// </summary>
/// <returns></returns>
private string GetWhereQueryKeyWordsExpression(string keywords)
{
return string.IsNullOrEmpty(keywords)
? ""
: $" AND (lower(\"description\") like lower('%{keywords}%'))" + $" AND (lower(\"detial\") like lower('%{keywords}%'))";
}
/// <summary>
/// 获取SQL查询语句中的分页表达式。
/// </summary>
/// <param name="countPerPage"></param>
/// <param name="currentPage"></param>
/// <returns></returns>
/// <exception cref="ArgumentOutOfRangeException"></exception>
private string GetPaginationExpression(int countPerPage, int currentPage)
{
if (countPerPage <= 0)
throw new ArgumentOutOfRangeException(nameof(countPerPage),
"the amount items per page can not be less than 1.");
if (currentPage <= 0)
throw new ArgumentOutOfRangeException(nameof(currentPage),
"the current page required can not be less than 1.");
return $" ORDER BY \"createtime\" LIMIT {countPerPage} OFFSET {countPerPage * (currentPage - 1)}";
}
/// <summary>
/// 查询当前条件下共有多少行数据。
/// <param name="isIncludeFilter">是否包含过滤条件。</param>
/// </summary>
public int QueryRowAmount(
DateTime begintime,
DateTime endtime,
string planname,
string module,
string itemparentname,
string itemname,
int index)
{
string s1 = GetEventCountSql(begintime, endtime);
string s2 = planname == "" ? "" : GetWherePlanExpression(planname, module);
string s3 = itemparentname == "" ? "" : GetWhereItemExpression(itemparentname, itemname, index);
//string s4 = keywords == "" ? "" : GetWhereQueryKeyWordsExpression(keywords);
var sql = s1 + s2 + s3;
var dt = QueryDataClient.Instance.Service.QueryData(sql);
// 未查询到任何数据。
if (dt == null || dt.Rows.Count <= 0 || dt.Columns.Count <= 0)
return 0;
// 返回满足当前条件的行数。
return int.Parse(dt.Rows[0][0].ToString());
}
/// <summary>
/// 查询符合条件的事件日志。
/// </summary>
/// <param name="page">待查询页码。0:查询所有数据而不分页;其它:查询指定的页码。</param>
/// <param name="isIncludeFilter">是否包含过滤条件。</param>
/// <exception cref="ArgumentOutOfRangeException">页码错误页码必须为大于等于0的整数。</exception>
/// <returns></returns>
public List<MaintainEventInfo> QueryEventLogs(
int page,
int pageSize,
DateTime begintime,
DateTime endtime,
string planname,
string module,
string itemparentname,
string itemname,
int index)
{
if (page < 0)
throw new ArgumentOutOfRangeException(nameof(page), "the page number must be greater than 0.");
string s1 = GetEventLogQuerySql(begintime, endtime);
string s2 = planname == "" ? "" : GetWherePlanExpression(planname, module);
string s3 = itemparentname == "" ? "" : GetWhereItemExpression(itemparentname, itemname, index);
//string s4 = keywords == "" ? "" : GetWhereQueryKeyWordsExpression(keywords);
var sql = s1 + s2 + s3;
// page == 0 表示查询所有数据仅导出Excel时使用。
if (page > 0)
sql += GetPaginationExpression(pageSize, page);
var dt = QueryDataClient.Instance.Service.QueryData(sql);
// 未查询到任何数据。
if (dt == null || dt.Rows.Count <= 0 || dt.Columns.Count <= 0)
return new List<MaintainEventInfo>();
var list = new List<MaintainEventInfo>();
foreach (var row in dt.Rows)
{
DataRow dr = row as DataRow;
try
{
MaintainEventInfo me = new MaintainEventInfo()
{
PlanName = dr[0].ToString(),
PlanModule = dr[1].ToString(),
ParentItemName = dr[2].ToString(),
ItemName = dr[3].ToString(),
Index = int.Parse(dr[4].ToString()),
MaintainTime = DateTime.Parse(dr[5].ToString()),
Recorder = dr[6].ToString(),
Record = dr[7].ToString()
};
list.Add(me);
}
catch (Exception ex)
{
continue;
}
}
return list;
}
#endregion
}
}