@@ -0,0 +1,43 @@ | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.Model | |||
{ | |||
public class Book | |||
{ | |||
public string Name { get; set; } | |||
public string Tag { get; set; } | |||
} | |||
public class BookEx : ObservableObject | |||
{ | |||
public Book BookN { get; private set; } | |||
private bool _isChecked=false; | |||
public bool IsChecked | |||
{ | |||
get | |||
{ | |||
return _isChecked; | |||
} | |||
set | |||
{ | |||
if (_isChecked != value) | |||
{ | |||
_isChecked = value; | |||
OnPropertyChanged("IsChecked"); | |||
} | |||
} | |||
} | |||
public BookEx(Book book) | |||
{ | |||
BookN = book; | |||
} | |||
} | |||
} |
@@ -12,6 +12,7 @@ | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.Business\BPASmartClient.Business.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.CustomResource\BPASmartClient.CustomResource.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.Helper\BPASmartClient.Helper.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.IoT\BPASmartClient.IoT.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" /> | |||
@@ -1,11 +1,20 @@ | |||
using BPASmartClient.Helper; | |||
using BPASmartClient.CustomResource.UserControls; | |||
using BPASmartClient.CustomResource.UserControls.MessageShow; | |||
using BPASmartClient.Helper; | |||
using BPASmartClient.Model; | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using Microsoft.Toolkit.Mvvm.Input; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.ComponentModel; | |||
using System.Data; | |||
using System.IO; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Text.RegularExpressions; | |||
using System.Threading.Tasks; | |||
using System.Windows.Media; | |||
namespace BPASmartClient.ViewModel | |||
{ | |||
@@ -24,25 +33,22 @@ namespace BPASmartClient.ViewModel | |||
#endregion | |||
#region 变量 | |||
/// <summary> | |||
/// 选中变量 | |||
/// </summary> | |||
private string _SelectCombox; | |||
public string SelectCombox | |||
string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}LogDir\\HBL.LogDir2022_5_13.log"; | |||
private string _SelectedText = ""; | |||
public string SelectedText | |||
{ | |||
get | |||
{ | |||
return _SelectCombox; | |||
return _SelectedText; | |||
} | |||
set | |||
{ | |||
if (_SelectCombox == value) | |||
if (_SelectedText == value) | |||
return; | |||
_SelectCombox = value; | |||
OnPropertyChanged("SelectCombox"); | |||
_SelectedText = value; | |||
OnPropertyChanged("SelectedText"); | |||
} | |||
} | |||
/// <summary> | |||
/// 时间条件 | |||
/// </summary> | |||
@@ -61,6 +67,54 @@ namespace BPASmartClient.ViewModel | |||
OnPropertyChanged("DateTimeStr"); | |||
} | |||
} | |||
public ObservableCollection<BookEx> SelectBookExs { set; get; } | |||
private ObservableCollection<BookEx> _books; | |||
public ObservableCollection<BookEx> BookExs | |||
{ | |||
get | |||
{ | |||
if (_books == null) | |||
{ | |||
_books = new ObservableCollection<BookEx>(); | |||
_books.CollectionChanged += (sender, e) => | |||
{ | |||
if (e.OldItems != null) | |||
{ | |||
foreach (BookEx bookEx in e.OldItems) | |||
{ | |||
bookEx.PropertyChanged -= ItemPropertyChanged; | |||
} | |||
} | |||
if (e.NewItems != null) | |||
{ | |||
foreach (BookEx bookEx in e.NewItems) | |||
{ | |||
bookEx.PropertyChanged += ItemPropertyChanged; | |||
} | |||
} | |||
}; | |||
} | |||
return _books; | |||
} | |||
} | |||
private ObservableCollection<LogModel> _LogModels; public ObservableCollection<LogModel> LogDataGrid | |||
{ | |||
get | |||
{ | |||
return _LogModels; | |||
} | |||
set | |||
{ | |||
if (_LogModels == value) | |||
return; | |||
_LogModels = value; | |||
OnPropertyChanged("LogDataGrid"); | |||
} | |||
} | |||
#endregion | |||
#region Command | |||
@@ -71,23 +125,148 @@ namespace BPASmartClient.ViewModel | |||
#region 函数 | |||
public void Init() | |||
{ | |||
LogDataGrid = new ObservableCollection<LogModel>(); | |||
DateTimeStr = DateTime.Now; | |||
BookExs.Add(new BookEx(new Book() { Name = "一般日志条件", Tag = "Info" }) { IsChecked = true }); | |||
BookExs.Add(new BookEx(new Book() { Name = "设备日志条件", Tag = "DeviceLog" })); | |||
BookExs.Add(new BookEx(new Book() { Name = "错误日志条件", Tag = "Error" })); | |||
BookExs.Add(new BookEx(new Book() { Name = "设备告警条件", Tag = "DeviceAlarm" })); | |||
SelectedText = "一般日志条件"; | |||
SelectBookExs = new ObservableCollection<BookEx>(); | |||
SelectBookExs.Add(new BookEx(new Book() { Name = "一般日志条件", Tag = "Info" }) { IsChecked = true }); | |||
//查询 | |||
QueryCommand = new RelayCommand(() => | |||
{ | |||
string sql = string.Empty; | |||
if (SelectBookExs.Count <= 0) | |||
{ | |||
NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"至少选中一个条件!"); | |||
return; | |||
} | |||
SelectBookExs?.ToList().ForEach(par => | |||
{ | |||
if (string.IsNullOrEmpty(sql)) | |||
sql += $"LOGGER='{par.BookN.Tag}'"; | |||
else | |||
sql += $" OR LOGGER='{par.BookN.Tag}'"; | |||
}); | |||
//1.找到某天的文件 | |||
string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}LogDir\\HBL.LogDir{DateTimeStr.ToString("yyyy_M_d")}.log"; | |||
if (File.Exists(path)) | |||
{ | |||
LogDataGrid.Clear(); | |||
//2.根据选中查询日志 | |||
DataTable dataTable = ReadFile(path); | |||
DataRow[] datas = dataTable.Select(sql); | |||
if (datas.Count() <= 0) | |||
{ | |||
NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"查询结果为空!"); | |||
return; | |||
} | |||
foreach (DataRow item in datas) | |||
{ | |||
LogDataGrid.Add(new LogModel | |||
{ | |||
time = item["TIME"].ToString(), | |||
type = item["LOGGER"].ToString(), | |||
message = item["MESSAGE"].ToString(), | |||
foreground = (item["LOGGER"].ToString() == "Error" || item["LOGGER"].ToString() == "DeviceAlarm") ? new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#ed0032")) : new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#21bb2e")) | |||
}); | |||
} | |||
} | |||
else | |||
{ | |||
NoticeDemoViewModel.OpenMsg(EnumPromptType.Info, MainViewModel.GetInstance().window, "提示", $"文件不存在,{path}!"); | |||
} | |||
}); | |||
//打开文件目录 | |||
OpenCommand = new RelayCommand(() => | |||
{ | |||
System.Diagnostics.Process.Start("Explorer", "/select," + logHelper.GetLogConfigInstance().directRollfileAppender.File); | |||
//logHelper.GetLogConfigInstance().OpenFile(logHelper.GetLogConfigInstance().directRollfileAppender.File); | |||
logHelper.GetLogConfigInstance().OpenFile(logHelper.GetLogConfigInstance().directRollfileAppender.File); | |||
}); | |||
} | |||
#endregion | |||
/// <summary> | |||
/// 查询告警或日志 | |||
/// </summary> | |||
/// <param name="time"></param> | |||
/// <param name="info"></param> | |||
public void QueryLogOrAlarm(DateTime time, string info) | |||
{ | |||
} | |||
/// <summary> | |||
/// 读取文件 | |||
/// </summary> | |||
/// <param name="path"></param> | |||
public DataTable ReadFile(string path) | |||
{ | |||
DataTable dt = new DataTable(); | |||
dt.Columns.AddRange(new[] | |||
{ | |||
new DataColumn("TIME"), | |||
new DataColumn("LOGGER"), | |||
new DataColumn("NAME"), | |||
new DataColumn("PRIORITY"), | |||
new DataColumn("MESSAGE"), | |||
}); | |||
//读取文件 | |||
string s = ""; | |||
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) | |||
{ | |||
using (StreamReader sr = new StreamReader(fs, System.Text.Encoding.Default)) | |||
{ | |||
s = sr.ReadToEnd(); | |||
} | |||
} | |||
//正则表达式匹配,注意RegexOptions.RightToLeft | |||
var matches = Regex.Matches(s, @"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([A-Z, ]{0,15}) ([A-Z,a-z]{0,20}) (\[\d{1}\]) (.*)", RegexOptions.RightToLeft); | |||
foreach (Match m in matches) | |||
{ | |||
var time = m.Groups[1].Value; | |||
var logger = m.Groups[2].Value; | |||
var name = m.Groups[3].Value; | |||
var priority = m.Groups[4].Value; | |||
var msg = m.Groups[5].Value; | |||
var dr = dt.NewRow(); | |||
dr.ItemArray = new[] { time, logger, name, priority, msg }; | |||
dt.Rows.InsertAt(dr, 0); | |||
} | |||
return dt; | |||
} | |||
/// <summary> | |||
/// 选中改变 | |||
/// </summary> | |||
/// <param name="sender"></param> | |||
/// <param name="e"></param> | |||
private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e) | |||
{ | |||
if (e.PropertyName == "IsChecked") | |||
{ | |||
BookEx bookEx = sender as BookEx; | |||
if (bookEx != null) | |||
{ | |||
IEnumerable<BookEx> bookExs = BookExs.Where(b => b.IsChecked == true); | |||
StringBuilder builder = new StringBuilder(); | |||
SelectBookExs.Clear(); | |||
foreach (BookEx item in bookExs) | |||
{ | |||
builder.Append(item.BookN.Name + " "); | |||
SelectBookExs.Add((BookEx)item); | |||
} | |||
SelectedText = builder == null ? string.Empty : builder.ToString(); | |||
} | |||
} | |||
} | |||
#endregion | |||
} | |||
@@ -236,6 +236,7 @@ namespace BPASmartClient.ViewModel | |||
if (_type == "Error") foreground = new SolidColorBrush((System.Windows.Media.Color)System.Windows.Media.ColorConverter.ConvertFromString("#ed0032")); | |||
OnPropertyChanged("type"); | |||
OnPropertyChanged("foreground"); | |||
} | |||
} | |||
public string message { get; set; } | |||
@@ -42,9 +42,13 @@ namespace BPASmartClient.ViewModel | |||
/// 是否告警 | |||
/// </summary> | |||
public AlarmModel IsAlarm { get; set; } | |||
public System.Windows.Window window; | |||
public DispatcherTimer dispatcherTimer; | |||
#region 单一 | |||
private volatile static MainViewModel _Instance; | |||
public static MainViewModel GetInstance() => _Instance ?? (_Instance = new MainViewModel()); | |||
#endregion | |||
public MainViewModel() | |||
{ | |||
@@ -4,6 +4,7 @@ | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:BPASmartClient.Control" | |||
xmlns:k="clr-namespace:BPASmartClient.Model;assembly=BPASmartClient.Model" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
d:DesignHeight="450" | |||
d:DesignWidth="800" | |||
@@ -25,11 +26,14 @@ | |||
<!-- 查询按钮栏 --> | |||
<StackPanel Margin="10,0,10,0" Orientation="Horizontal"> | |||
<ComboBox Width="80" SelectedIndex="0" SelectedItem="{Binding SelectCombox}"> | |||
<ComboBoxItem Tag="Info">一般日志</ComboBoxItem> | |||
<ComboBoxItem Tag="DeviceLog">设备日志</ComboBoxItem> | |||
<ComboBoxItem Tag="Error">错误日志</ComboBoxItem> | |||
<ComboBoxItem Tag="DeviceAlarm">设备告警</ComboBoxItem> | |||
<ComboBox Width="120" Text="{Binding SelectedText}" IsEditable="True" ItemsSource="{Binding Path=BookExs}"> | |||
<ComboBox.ItemTemplate> | |||
<DataTemplate DataType="{x:Type k:BookEx}"> | |||
<StackPanel Orientation="Horizontal"> | |||
<CheckBox IsChecked="{Binding IsChecked}" Margin="2,0,3,0" Background="Red" Content="{Binding BookN.Name}" /> | |||
</StackPanel> | |||
</DataTemplate> | |||
</ComboBox.ItemTemplate> | |||
</ComboBox> | |||
<DatePicker Margin="10,0,10,0" Text="{Binding DateTimeStr,Mode=TwoWay,NotifyOnTargetUpdated=True}"></DatePicker> | |||
<Button Margin="10,0,0,0" Cursor="Hand" Command="{Binding QueryCommand}" Style="{DynamicResource CommonBtn_返回}" Width="75">查询数据</Button> | |||
@@ -38,95 +42,41 @@ | |||
<!-- 表格栏 --> | |||
<Grid Grid.Row="1"> | |||
<DataGrid | |||
x:Name="datagrid" | |||
Grid.Row="2" | |||
Margin="10" | |||
ItemsSource="{Binding EquiPment1, UpdateSourceTrigger=PropertyChanged}"> | |||
<DataGrid Margin="10" ItemsSource="{Binding LogDataGrid, UpdateSourceTrigger=PropertyChanged}" Grid.Row="2"> | |||
<DataGrid.Columns> | |||
<DataGridTemplateColumn Width="2*" Header="紧急程度"> | |||
<DataGridTemplateColumn Header="日志时间" Width="300"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<Ellipse | |||
Width="12" | |||
Height="12" | |||
Fill="{Binding color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" | |||
ToolTip="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock HorizontalAlignment="Center" Text="{Binding time, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="14" Foreground="{Binding foreground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="报警时间或恢复时间"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="类型"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="状态"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="变量名"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="报警值或恢复值"> | |||
<!--<DataGridTemplateColumn Header="设备ID" Width="100"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock HorizontalAlignment="Center" Text="{Binding deviceId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="14" Foreground="{Binding foreground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="4.4*" Header="参考值"> | |||
</DataGridTemplateColumn>--> | |||
<DataGridTemplateColumn Header="日志类型" Width="300"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock HorizontalAlignment="Center" Text="{Binding type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="14" Foreground="{Binding foreground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Width="2*" Header="操作"> | |||
<DataGridTemplateColumn Header="日志内容" Width="*"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
Foreground="#00ccff" | |||
Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> | |||
<TextBlock HorizontalAlignment="Left" Text="{Binding message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="14" Foreground="{Binding foreground, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
</DataGrid.Columns> | |||
</DataGrid> | |||
</Grid> | |||
</Grid> | |||
</UserControl> |
@@ -26,5 +26,15 @@ namespace BPASmartClient.Control | |||
InitializeComponent(); | |||
this.DataContext = LogOrAlarmViewModel.GetInstance(); | |||
} | |||
private void CheckBox_Checked(object sender, RoutedEventArgs e) | |||
{ | |||
} | |||
private void CheckBox_Unchecked(object sender, RoutedEventArgs e) | |||
{ | |||
} | |||
} | |||
} |
@@ -25,9 +25,7 @@ | |||
</ResourceDictionary.MergedDictionaries> | |||
</ResourceDictionary> | |||
</Window.Resources> | |||
<Window.DataContext> | |||
<vm:MainViewModel /> | |||
</Window.DataContext> | |||
<Border x:Name="br" Style="{DynamicResource border主窗体背景}"> | |||
<Grid> | |||
@@ -10,6 +10,7 @@ using BPASmartClient.Message; | |||
using BPASmartClient.Model; | |||
using BPASmartClient.Model.冰淇淋.Enum; | |||
using BPASmartClient.Model.咖啡机.Enum; | |||
using BPASmartClient.ViewModel; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
@@ -35,7 +36,9 @@ namespace BPASmartClient | |||
{ | |||
public MainWindow() | |||
{ | |||
InitializeComponent(); | |||
InitializeComponent(); | |||
MainViewModel.GetInstance().window = this; | |||
this.DataContext = MainViewModel.GetInstance(); | |||
Initialize(); | |||
} | |||