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,效果展示

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM