zoukankan      html  css  js  c++  java
  • C#运动控制日志报警记录和操作记录记录查询(SqlLite数据库操作)

    以下是学习笔记

    【分析】要记录哪些内容?有哪些分类?

    操作记录:参数设置,手动控制(点了哪个控制按钮等),登录,退出。

    日志信息:监控窗体的AddLog日志列表同时也写入数据库

    报警信息:监控窗体的AddAlarm显示同事也写入数据库;打开不到位报警,伺服报警。

    1,报警信息的界面UI

     2,实体类

    namespace AutomaticStoreMotionModels
    {
        /// <summary>
        /// 日志类
        /// </summary>
       public class SysLog
        {
            public SysLog()
            {
                
            }
            public SysLog(string logInfo,string logAlarmState,LogTye logType,string user)
            {
                this.LogTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                this.LogInfo = logInfo;
                this.LogAlarmState = logAlarmState;
                this.LogType = logType;
                this.User = user;
            }
    
            public string LogTime { get; set; }
            public string LogInfo { get; set; }
            /// <summary>
            /// 记录报警状态,是触发报警还是消除报警
            /// </summary>
            public string LogAlarmState { get; set; }
            /// <summary>
            /// 日志类型(枚举)
            /// </summary>
            public LogTye LogType { get; set; }
            public string User { get; set; }
        }
    
        /// <summary>
        /// 日志类型
        /// </summary>
        public enum LogTye
        {
            日志信息,
            报警信息,
            操作记录
        }
    
    }
    

      

    实体类的类名,属性要和数据表名,字段保持一致

    3,DAL数据查询类

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using AutomaticStoreMotionModels;
    using SqlSugar;
    
    namespace AutomaticStoreMotionDal
    {
        public class SysLogService
        {
    
            /// <summary>
            /// 插入一条记录
            /// </summary>
            /// <param name="log">日志记录对象</param>
            /// <returns>是否成功</returns>
            public static bool AddSysLog(SysLog log)
            {
                return SqlSugarHelper.SqlSugarClient.Insertable(log).ExecuteCommand() == 1;
            }
    
            /// <summary>
            /// 查询日志信息
            /// </summary>
            /// <param name="start">开始时间</param>
            /// <param name="end">结束时间</param>
            /// <param name="logtype">日志类型</param>
            /// <param name="logAlarmState">报警状态</param>
            /// <returns></returns>
            public static List<SysLog> GetSysLogByCondiiton(string start, string end, string logtype, string logAlarmState)
            {
                //根据时间查询
                var query = SqlSugarHelper.SqlSugarClient.Queryable<SysLog>()
                    .Where(c => SqlFunc.Between(c.LogTime, start, end));
    
                //日志类型
                if (logtype.Length > 0)
                {
                    query.Where(c => c.LogType == (LogTye)Enum.Parse(typeof(LogTye),logtype));
                }
    
                //报警状态
                if (logAlarmState.Length > 0)
                {
                    query.Where(c => c.LogAlarmState==logAlarmState);
                }
    
                return query.ToList();
            }
        }
    
    }
    

     

    4,使用

    【4.1】 登录成功记录

     【4.2】系统退出记录

            private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                //写入数据库
                if (!SysLogService.AddSysLog(new SysLog("系统退出", "触发", LogTye.操作记录, Program.GlobalSysAdmin.LoginName)))
                {
                    NLogHelper.Error("日志信息写入数据库出错");
                };
    
                cts.Cancel();
            }
    

     

    【4.3】 参数修改记录

            /// <summary>
            /// 修改参数
            /// </summary>
            /// <typeparam name="T">对象类型</typeparam>
            /// <param name="parameterType">参数类型</param>
            /// <param name="obj">对象</param>
            private void ModifyParameter<T>(string parameterType,T obj)
            {
                StringBuilder sb=new StringBuilder();
    
                foreach (var item in this.tab_main.SelectedTab.Controls)
                {
                    if (item is NumericUpDown numeric)
                    {
                        //获取控件的名称(控件的名称对应的是对象属性的名称)
                        string propertyName = numeric.Name;
                        //通过对象属性名称拿到属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
    
                        //如果控制的值和对象属性的值不一致,表示有修改动作
                        if (value.Length>0&& numeric.Value.ToString() != value)
                        {
                            //添加修改记录
                            sb.Append(numeric.Tag.ToString() + "修改为:" + numeric.Value.ToString() + "; ");
                            SetObjectPropertyVaule(obj, propertyName, numeric.Value.ToString());
                        }
                    }
                    else if(item is ComboBox cmb)
                    {
                        //获取控件的名称(控件的名称对应的是对象属性的名称)
                        string propertyName = cmb.Name;
                        //通过对象属性名称拿到属性的值
                        string value = GetObjectPropertyVaule(obj, propertyName);
                        //如果控制的值和对象属性的值不一致,表示有修改动作
                        if (value.Length > 0 && cmb.Text != value)
                        {
                            //添加修改记录
                            sb.Append(cmb.Tag.ToString() + "修改为:" + cmb.Text.ToString() + "; ");
                            SetObjectPropertyVaule(obj, propertyName, cmb.Text.ToString());
                        }
                    }               
                }
    
                if (sb.ToString().Length > 0)
                {
                    OperationResult result = parameterType == "基础参数"
                        ? motionEx.SaveBasicParmetmer()
                        : motionEx.SaveAdvancedParmetmer();
                    if (result.IsSuccess)
                    {
                        //写入数据库
                        if (!SysLogService.AddSysLog(new SysLog(sb.ToString(), "触发", LogTye.操作记录, Program.GlobalSysAdmin.LoginName)))
                        {
                            NLogHelper.Error("参数修改记录写入数据库出错");
                        };
    
                        MessageBox.Show(parameterType+"修改成功", "参数修改");
         
                    }
                    else
                    {
                        MessageBox.Show(parameterType + "修改失败", "参数修改");
                    }
                }
                else
                {
                    MessageBox.Show("参数未做任何修改", "参数修改");
                }
            }
    

      

    【4.4】日志信息和报警信息

            /// <summary>
            /// 添加日志信息
            /// </summary>
            /// <param name="index">日志等级(0:info,1:warning,2:error)</param>
            /// <param name="log">日志信息</param>
            public void AddLog(int index, string log)
            {
                if (!this.lvw_info.InvokeRequired)//如果没有跨线程访问
                {
                    ListViewItem lstItem=new ListViewItem(CurrentTime,index);
                    lstItem.SubItems.Add(log);
                    this.lvw_info.Items.Insert(0, lstItem);//保证最新的显示在第一条
                    //只保留最后100条记录
                    if (lvw_info.Items.Count > 100)
                    {
                        lvw_info.Items.RemoveAt(100);
                    }
                }
                else//如果有线程从多线程使用
                {
                    this.lvw_info.Invoke(new Action(() =>
                    {
                        ListViewItem lstItem = new ListViewItem(CurrentTime, index);
                        lstItem.SubItems.Add(log);
                        this.lvw_info.Items.Insert(0, lstItem);//保证最新的显示在第一条
                        //只保留最后100条记录
                        if (lvw_info.Items.Count > 100)
                        {
                            lvw_info.Items.RemoveAt(100);
                        }
                    }));
                }
    
                //写入数据库
                if (!SysLogService.AddSysLog(new SysLog(log, "触发", LogTye.日志信息, Program.GlobalSysAdmin.LoginName)))
                {
                    NLogHelper.Error("日志信息写入数据库出错");
                };
    
            }
    
            /// <summary>
            /// 【报警显示步骤2】在监控窗体添加报警委托的原型
            /// </summary>
            /// <param name="info">报警信息</param>
            /// <param name="isAck">触发报警还是消除报警</param>
            public void AddAlarm(string info, bool isAck)
            {
                if (isAck)
                {
                    //如果
                    if (!AlarmInfoList.Contains(info))
                    {
                        AlarmInfoList.Add(info);
                    }
                }
                else
                {
                    if (AlarmInfoList.Contains(info))
                    {
                        AlarmInfoList.Remove(info);
                    }
                }
                //刷新界面
                RefreshAlarm();
    
                //写入数据库
                if (!SysLogService.AddSysLog(new SysLog(info,isAck? "触发":"消除", LogTye.日志信息, Program.GlobalSysAdmin.LoginName)))
                {
                    NLogHelper.Error("日志信息写入数据库出错");
                };
            }
    

     

    5,报警查询界面的代码编写:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using AutomaticStoreMotionDal;
    using AutomaticStoreMotionModels;
    
    namespace AutomaticStoreMotionPro
    {
        public partial class FrmSysLog : Form
        {
            public FrmSysLog()
            {
                InitializeComponent();
    
                //关闭自动创建列
                this.dgv_data.AutoGenerateColumns = false;
    
                //AutoSizeColumnsMode要设置为None,下面设置的固定宽度才有效果
                this.dgv_data.AutoSizeColumnsMode= System.Windows.Forms.DataGridViewAutoSizeColumnsMode.None;
    
                this.dgv_data.Columns[0].Width = 150;
                this.dgv_data.Columns[1].AutoSizeMode=DataGridViewAutoSizeColumnMode.Fill;//这一列设置自动填充显示的跨度
                this.dgv_data.Columns[2].Width = 100;
                this.dgv_data.Columns[3].Width = 100;
                this.dgv_data.Columns[4].Width = 100;
    
    
    
                this.chk_logInfo.Checked = true;
                this.rdb_ack.Checked = true;
    
                this.dtp_start.Value = this.dtp_end.Value.AddHours(-3.0);
            }
    
            private void btn_query_Click(object sender, EventArgs e)
            {
                Task.Run(() => {
                    this.Invoke(new Action(() =>
                    {
                        QueryProcess(DateTime.Now.ToString(this.dtp_start.Text), DateTime.Now.ToString(this.dtp_end.Text), GetLogType(), GetLogAlarmState());
                    }));
                });
            }
    
            private void btn_queryToay_Click(object sender, EventArgs e)
            {
                Task.Run(() => { this.Invoke(new Action(() =>
                {
                    QueryProcess(DateTime.Now.ToString("yyyy-MM-dd 00:00:00"), DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),GetLogType(),GetLogAlarmState());
                })); });
            }
    
            /// <summary>
            /// 获取日志类型(查询条件,可以多选)
            /// </summary>
            /// <returns></returns>
            private List<string> GetLogType()
            {
                List<string> result=new List<string>();
                if (chk_logInfo.Checked)
                {
                    result.Add(this.chk_logInfo.Text);
                }
                if (chk_alarmInfo.Checked)
                {
                    result.Add(this.chk_alarmInfo.Text);
                }
                if (chk_operationInfo.Checked)
                {
                    result.Add(this.chk_operationInfo.Text);
                }
    
                return result;
            }
    
            /// <summary>
            /// 获取报警状态(查询条件,只能单选)
            /// </summary>
            /// <returns></returns>
            private string GetLogAlarmState()
            {
                if (rdb_ack.Checked)
                {
                    return "触发";
                }
                else if(rdb_unAck.Checked)
                {
                    return "消除";
                }
                else
                {
                    return "全部";
                }
            }
    
            /// <summary>
            /// 通用的查询方法
            /// </summary>
            /// <param name="start"></param>
            /// <param name="end"></param>
            /// <param name="logtype"></param>
            /// <param name="logAlarmState"></param>
            private void QueryProcess(string start, string end,List<string> logtype, string logAlarmState)
            {
                DateTime t1 = Convert.ToDateTime(start);
                DateTime t2 = Convert.ToDateTime(end);
    
                if (t1 > t2)
                {
                    new FrmConfirmSingle("日志查询", "开始时间不能大于结束时间") {TopMost = true}.ShowDialog();
                    return;
                }
    
                if (logAlarmState == "全部")
                {
                    logAlarmState = string.Empty;
                }
    
                var List=new List<SysLog>();
    
                if (logtype.Count > 0)
                {
                    foreach (var item in logtype)
                    {
                        List.AddRange(SysLogService.GetSysLogByCondiiton(start,end,item,logAlarmState));
                    }
                }
    
                //排序【这个排序很重要,因为是根据日志类型分组查询的,导致List是根据分组来排列显示的,要用这个排序方法来设置按照时间顺序显示】
                List.Sort((p1, p2) =>
                {
                    if (Convert.ToDateTime(p1.LogTime) > Convert.ToDateTime(p2.LogTime))
                    {
                        return 1;
                    }
                    else if (Convert.ToDateTime(p1.LogTime) < Convert.ToDateTime(p2.LogTime))
                    {
                        return -1;
                    }
                    else
                    {
                        return 0;
                    }
                });
    
                this.dgv_data.DataSource = null;
                this.dgv_data.DataSource = List;
            }
    
            private void btn_export_Click(object sender, EventArgs e)
            {
    
                   string filePath= ExcelHelper.ExportToExcel(this.dgv_data);
                   if (filePath!=null)
                   {
                       new FrmConfirmSingle("日志导出", "日志记录导出成功") { TopMost = true }.ShowDialog();
                   }
                   else
                   {
                    new FrmConfirmSingle("日志导出", "日志记录导出失败:") { TopMost = true }.ShowDialog();
                }
                    
            }
        }
    }
    

      

    6,效果展示

     

  • 相关阅读:
    Java知多少(28)super关键字
    Java知多少(27)继承的概念与实现
    Java知多少(26)源文件的声明规则
    Java知多少(25)再谈Java包
    Java知多少(24)包装类、拆箱和装箱详解
    Java知多少(23)类的基本运行顺序
    Java知多少(22)方法重载
    Java知多少(21)this关键字详解
    Java知多少(20)变量的作用域
    Java知多少(19)访问修饰符(访问控制符)
  • 原文地址:https://www.cnblogs.com/baozi789654/p/15707721.html
Copyright © 2011-2022 走看看