Commit 092e1146 authored by 潘栩锋's avatar 潘栩锋 🚴

添加 右上角 顶上,全局的报警提示

parent 06d88f6d
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using FObjBase;
using FLY.OBJComponents.Common;
using FLY.OBJComponents.IService;
using FLY.OBJComponents.OBJ_INTERFACE;
using Newtonsoft.Json;
namespace FLY.OBJComponents.Client
{
public class WarningSystem2ServiceClient : FObjBase.Reflect.Reflect_SeviceClient, IWarningSystem2Service
{
protected override Type InterfaceType => typeof(IWarningSystem2Service);
#region IWarningSystem2Service
public bool Enable { get; set; }
public bool IsRinging { get; set; }
public FlyData_WarningHistory[] ReasonList { get; set; }
/// <summary>
/// 最后一条数据Id
/// </summary>
public long LastId { get; set; }
#endregion
public WarningSystem2ServiceClient(UInt32 serviceId) : base(serviceId) { }
public WarningSystem2ServiceClient(UInt32 serviceId, string connName) : base(serviceId, connName) { }
public void Reset()
{
Call(nameof(Reset));
}
public void Silence()
{
Call(nameof(Silence));
}
/// <summary>
/// 获取纵向趋势图
/// </summary>
/// <param name="request"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
public void GetTrend(
Pack_GetTrendRequest request,
AsyncCBHandler asyncDelegate, object asyncContext)
{
Call(nameof(GetTrend), new { request }, asyncDelegate, asyncContext);
}
}
}
using FLY.OBJComponents.Common;
using FLY.OBJComponents.Server.Model;
using FObjBase;
using FObjBase.Reflect;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.OBJComponents.IService
{
/// <summary>
/// 报警管理系统,配置,整个历史列表
/// </summary>
public interface IWarningSystem2Service : INotifyPropertyChanged
{
/// <summary>
/// 报警使能
/// </summary>
bool Enable { get; set; }
/// <summary>
/// 正在响铃
/// </summary>
bool IsRinging { get; }
/// <summary>
/// 复位,把全部报警消失
/// </summary>
void Reset();
/// <summary>
/// 静音,不消失报警,只是静音,新的报警来,还是会响
/// </summary>
void Silence();
/// <summary>
/// 当前报警列表
/// </summary>
FlyData_WarningHistory[] ReasonList { get; }
/// <summary>
/// 最后一条数据Id
/// </summary>
long LastId { get; }
/// <summary>
/// 获取纵向趋势图
/// </summary>
/// <param name="request"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
[Call(typeof(Pack_GetTrendReponse<FlyData_WarningHistory>))]
void GetTrend(
Pack_GetTrendRequest request,
AsyncCBHandler asyncDelegate, object asyncContext);
}
}
using FLY.OBJComponents.Common;
using FLY.OBJComponents.IService;
using FObjBase;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.OBJComponents.Server
{
/// <summary>
/// 报警管理系统
/// </summary>
public class WarningSystem2 : IWarningSystem2Service
{
public event PropertyChangedEventHandler PropertyChanged;
#region IWarningSystem2Service
/// <summary>
/// 使能
/// </summary>
public bool Enable { get; set; }
/// <summary>
/// 正在响铃
/// </summary>
public bool IsRinging { get; private set; }
/// <summary>
/// 当前正在报警的!!!!!!
/// </summary>
public FlyData_WarningHistory[] ReasonList { get; private set; }
/// <summary>
/// 最后一条数据Id
/// </summary>
public long LastId { get; set; }
#endregion
/// <summary>
/// ReasonList 的原始数据, errors 与 ReasonList 需要同步
/// </summary>
private List<FlyData_WarningHistory> errors = new List<FlyData_WarningHistory>();
/// <summary>
/// 保存到SQL数据库的集成工具
/// </summary>
BufferError errorBuffer;
public WarningSystem2()
{
Enable = true;
}
public void Init(BufferError errorBuffer)
{
this.errorBuffer = errorBuffer;
Misc.BindingOperations.SetBinding(this.errorBuffer, nameof(this.errorBuffer.LastId), this, nameof(LastId));
}
public void Reset()
{
errors.Clear();
updateReasonList();
}
public void Silence()
{
IsRinging = false;
}
#region IWarningServiceSimple
public void Add(int errcode, string description)
{
Add(errcode, description, ERR_STATE.ON);
}
public void Add(int errcode, string description, string accessory)
{
Add(errcode, description, ERR_STATE.ON, accessory, false);
}
public void Add(int errcode, string description, ERR_STATE state)
{
Add(errcode, description, state, "", false );
}
public void Update(int errcode, string description)
{
Update(errcode, description, "");
}
public void Update(int errcode, string description, string accessory)
{
Add(errcode, description, ERR_STATE.ON, accessory, true);
}
/// <summary>
///
/// </summary>
/// <param name="errcode">报警码</param>
/// <param name="description">描述</param>
/// <param name="state">状态,ON or OFF</param>
/// <param name="accessory">附加信息</param>
/// <param name="isUpdate">就算已经存在,也有刷新</param>
public void Add(int errcode, string description, ERR_STATE state, string accessory, bool isUpdate)
{
if (!Enable)
return;
if (state == ERR_STATE.OFF)
{
Remove(errcode);
return;
}
if (errors.Count > 0)
{
//查找是否已经存在
var error = errors.Find(err => err.ErrCode == errcode);
if (error != null) {
//已经有了
if (!isUpdate)
{
//不需要刷新
return;
}
else {
//需要刷新
//先把它删除
errors.Remove(error);
}
}
}
{
//这是新的记录
FlyData_WarningHistory error = new FlyData_WarningHistory
{
Time = DateTime.Now,
ErrCode = errcode,
Description = description,
State = state,
Accessory = accessory
};
errors.Add(error);
updateReasonList();
errorBuffer.Add(error);
}
}
void updateReasonList() {
if (errors.Count() > 0)
ReasonList = errors.ToArray();
else
ReasonList = null;
IsRinging = errors.Count > 0;
}
public void Remove(int errcode) {
FlyData_WarningHistory error = null;
if (errors.Count()==0)
return;
//删除!!!!!
error = errors.Find(err => err.ErrCode == errcode);
if (error == null)
return;
errors.Remove(error);
updateReasonList();
errorBuffer.Add(new FlyData_WarningHistory
{
Time = DateTime.Now,
ErrCode = errcode,
Description = error.Description,
State = ERR_STATE.OFF
});
}
#endregion
/// <summary>
/// 获取纵向趋势图
/// </summary>
/// <param name="request"></param>
/// <param name="asyncDelegate"></param>
/// <param name="asyncContext"></param>
public void GetTrend(
Pack_GetTrendRequest request,
AsyncCBHandler asyncDelegate, object asyncContext)
{
errorBuffer.GetTrend(request, asyncDelegate, asyncContext);
}
}
}
using FLY.OBJComponents.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Thick.Base.UI
{
public class WarningSystem2ServiceClientWithName : WarningSystem2ServiceClient
{
public string DevName { get; private set; }
public WarningSystem2ServiceClientWithName(UInt32 serviceId, string devName) : base(serviceId)
{
DevName = devName;
}
public WarningSystem2ServiceClientWithName(UInt32 serviceId, string connName, string devName) : base(serviceId, connName)
{
DevName = devName;
}
}
}
using FLY.OBJComponents.IService;
using MultiLayout.UiModule;
using Misc;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using FLY.Thick.Base.UI;
using Unity;
using FLY.Thick.Base.Common;
using MultiLayout;
using System.Windows.Threading;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace FLY.Thick.Base.UI.OnInit
{
public class OnInitWarnings : IOnInit
{
public int Level { get; private set; }
WarningSystemManager warningSystemManager;
IUnityContainer container;
FlyLayoutManager flyLayoutManager;
DispatcherTimer timer_error;
int reason_list_index = -1;
public OnInitWarnings(
IUnityContainer container,
FlyLayoutManager flyLayoutManager,
WarningSystemManager warningSystemManager,
int lv = 1)
{
Level = lv;
this.container = container;
this.flyLayoutManager = flyLayoutManager;
this.warningSystemManager = warningSystemManager;
if (warningSystemManager.Warnings.Count() == 0)
return;
this.flyLayoutManager.ErrMsgClick = ErrMsg_OnClick;
}
public void OnInit()
{
if (warningSystemManager.Warnings.Count() == 0)
return;
warningSystemManager.PropertyChanged += WarningSystemManager_PropertyChanged;
//报警原因轮流显示
timer_error = new DispatcherTimer();
timer_error.Interval = TimeSpan.FromSeconds(3);
timer_error.Tick += (s, e) =>
{
reason_list_index--;
if (reason_list_index < 0)
reason_list_index = warningSystemManager.Errors.Count();
UpdateError();
};
UpdateError();
}
private void WarningSystemManager_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(warningSystemManager.Errors)) {
reason_list_index = warningSystemManager.Errors.Count() - 1;
UpdateError();
}
}
void UpdateError()
{
if (warningSystemManager.Errors.Count() == 0)
{
flyLayoutManager.ErrMsg = null;
timer_error.Stop();
}
else {
if (reason_list_index < 0)
reason_list_index = 0;
else if (reason_list_index > warningSystemManager.Errors.Count() - 1) {
reason_list_index = warningSystemManager.Errors.Count() - 1;
}
var err = warningSystemManager.Errors[reason_list_index];
flyLayoutManager.ErrMsg = $"{err.DevName} {err.Description}";
timer_error.Start();
}
}
private void ErrMsg_OnClick() {
//打开管理页面
var p = container.Resolve<PgErrorsTable>();
FlyLayoutManager.NavigationService.Navigate(p);
}
}
public class WarningSystemManager : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public List<WarningSystem2ServiceClientWithName> Warnings { get; private set; } = new List<WarningSystem2ServiceClientWithName>();
public List<ErrorWithName> Errors { get; private set; } = new List<ErrorWithName>();
[InjectionMethod]
public void Init(IUnityContainer container)
{
//找到 warnings.service 容器
if (!container.IsRegistered<IUnityContainer>("warnings.service"))
return;
var warning_container = container.Resolve<IUnityContainer>("warnings.service");
//获取全部报警管理器
Warnings = warning_container.ResolveAll<WarningSystem2ServiceClientWithName>().ToList();
foreach (var warning in Warnings)
{
warning.PropertyChanged += WarningService_PropertyChanged;
}
updateErrors();
}
private void WarningService_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if ((e.PropertyName == nameof(WarningSystem2ServiceClientWithName.ReasonList))
||(e.PropertyName == nameof(WarningSystem2ServiceClientWithName.IsConnected)))
{
updateErrors();
}
}
void updateErrors()
{
List<ErrorWithName> errors = new List<ErrorWithName>();
foreach (var warning in Warnings)
{
if (!warning.IsConnected)
{
errors.Add(new ErrorWithName()
{
DevName = warning.DevName,
Time = DateTime.Now,
ErrCode = 0,
Description = "服务器连接断开"
});
}
else if (warning.ReasonList != null && warning.ReasonList.Count() > 0) {
errors.AddRange(warning.ReasonList.Select(e =>
new ErrorWithName()
{
DevName = warning.DevName,
Time = e.Time,
ErrCode = e.ErrCode,
Description = e.Description
}));
}
}
if (errors.Count > 0)
{
errors.Sort((e1, e2) =>
{
return e1.Time.CompareTo(e2.Time);
});
Errors = errors;
}
else {
Errors = new List<ErrorWithName>();
}
}
}
public class ErrorWithName:INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// 设备名称
/// </summary>
public string DevName { get; set; }
/// <summary>
/// 时间
/// </summary>
public DateTime Time { get; set; }
/// <summary>
/// 出错码
/// </summary>
public int ErrCode { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
}
}
<Page x:Class="FLY.Thick.Base.UI.PgErrorsTable"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
mc:Ignorable="d"
d:DesignHeight="768" d:DesignWidth="1024"
Background="White"
Title="Page_WarningSystem">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/FLY.ControlLibrary;component/Themes/Dictionary_MyStyle.xaml"/>
<ResourceDictionary Source="pack://application:,,,/FLY.Thick.Base.UI;component/Converter/Dictionary_MyConv.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="Control" x:Key="iconPackStyle">
<Setter Property="Width" Value="25"/>
<Setter Property="Height" Value="auto"/>
<Setter Property="MaxHeight" Value="25"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<Style TargetType="Ellipse" x:Key="backPackStyle">
<Setter Property="Width" Value="50"/>
<Setter Property="Height" Value="50"/>
<Setter Property="Fill" Value="{StaticResource Color_theme_static}"/>
</Style>
<Style TargetType="TextBlock" x:Key="titlePackStyle">
<Setter Property="Margin" Value="2"/>
<Setter Property="FontSize" Value="16"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style TargetType="Button" x:Key="buttonStyle" BasedOn="{StaticResource Styles.Button.Empty}">
<Setter Property="Margin" Value="20,0"/>
<Setter Property="Foreground" Value="White"/>
</Style>
</ResourceDictionary>
</Page.Resources>
<Grid Name="root_grid" >
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Background="{StaticResource Brushes.TitleBar.Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" >
<Button Style="{StaticResource Styles.TitleBar.BackButton2}" Click="button_back_Click" />
<TextBlock Style="{StaticResource Styles.TitleBar.Text}" Text="报警"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" Margin="60,0,0,0">
<Button Style="{StaticResource buttonStyle}" Click="button_reset_click">
<StackPanel>
<Grid Style="{StaticResource Styles.Shadow}">
<Ellipse Style="{StaticResource backPackStyle}" Fill="#FFEE3232" />
<iconPacks:PackIconMaterial Kind="RestartAlert" Style="{StaticResource iconPackStyle}" />
</Grid>
<TextBlock Text="复位" Style="{StaticResource titlePackStyle}"/>
</StackPanel>
</Button>
<Button Style="{StaticResource buttonStyle}" Click="button_database_click" >
<StackPanel>
<Grid Style="{StaticResource Styles.Shadow}">
<Ellipse Style="{StaticResource backPackStyle}" />
<iconPacks:PackIconMaterial Kind="DatabaseSearch" Style="{StaticResource iconPackStyle}"/>
</Grid>
<TextBlock Text="查询" Style="{StaticResource titlePackStyle}"/>
</StackPanel>
</Button>
<ComboBox x:Name="cbSelectList" Width="191" Height="40" FontSize="20" FontWeight ="Bold"
ItemsSource="{Binding Warnings}"
DisplayMemberPath="DevName"/>
</StackPanel>
</StackPanel>
</Grid>
<DataGrid Grid.Row="1" ItemsSource="{Binding Errors}" AutoGenerateColumns="False" IsReadOnly="True" Margin="{StaticResource ControlMargin}"
AlternationCount ="2"
AlternatingRowBackground="LightGray"
RowHeaderWidth="0"
Style="{DynamicResource MahApps.Styles.DataGrid.Azure}"
FontSize="20"
>
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding DevName}" Header="设备名称"/>
<DataGridTextColumn Binding="{Binding Time,StringFormat={}{0:MM/dd HH:mm}}" Header="时间" />
<DataGridTextColumn Binding="{Binding ErrCode}" Header="代码"/>
<DataGridTextColumn Binding="{Binding Description}" Header="描述"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Page>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Net;
using FLY.Thick.Base.Client;
using Unity;
using FLY.Thick.Base.UI.OnInit;
using MultiLayout;
namespace FLY.Thick.Base.UI
{
/// <summary>
/// Page_ErrorTable.xaml 的交互逻辑
/// </summary>
public partial class PgErrorsTable : Page
{
WarningSystemManager warningSystemManager;
IUnityContainer container;
FlyLayoutManager manager;
/// <summary>
///
/// </summary>
public PgErrorsTable()
{
InitializeComponent();
}
[InjectionMethod]
public void Init(
FlyLayoutManager manager,
IUnityContainer container,
WarningSystemManager warningSystemManager
)
{
this.manager = manager;
this.container = container;
this.warningSystemManager = warningSystemManager;
this.DataContext = warningSystemManager;
manager.IsInOption = true;
cbSelectList.SelectedIndex = 0;
}
private void button_back_Click(object sender, RoutedEventArgs e)
{
manager.IsInOption = false;
NavigationService.GoBack();
}
private void button_reset_click(object sender, RoutedEventArgs e)
{
foreach (var warning in warningSystemManager.Warnings) {
warning.Reset();
}
}
private void button_database_click(object sender, RoutedEventArgs e)
{
var warning = (WarningSystem2ServiceClientWithName)cbSelectList.SelectedItem;
if (warning == null)
return;
PgErrorAllTable p = container.Resolve<PgErrorAllTable>(
new Unity.Resolution.ParameterOverride("warning", warning));
NavigationService.Navigate(p);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment