zoukankan      html  css  js  c++  java
  • 系统操作日志设计代码实现

    上一篇《系统操作日志设计》,已基本介绍了为什么要系统操作日志和设计系统操作日志部分内容,如不清楚系统操作日志的请点这里。 :)

          通了解《系统操作日志设计》,已基本明确我们不能通过clone的方式来做日志的设计,因为这样不仅会造成的你数据库表爆炸的情况,还大大的增加了工作量,减少了系统的可维护性。

          通过思考大概清楚系统操作日志的设计,以下是其UML图:

    通过上图,我们可以了解知道该UML主要由三个表组成,其中一个主表LogSetting和两个从表分别是LogOperation和LogSettingDetail。

    那么怎么样才能通过这样的设计来现实我们的日志功能呢?

    其实一开始我就觉得通过.net的反射功能可以很简单、很方便的实现这个功能,所以我就顺着一个思路来实现她;通过反射动态的获取Model实体的属性,然后再根据LogSettingDetail配置来匹配所要记录的字段信息。

    先来主要的代码吧,发现将思想用文字表达出来还是较困难的,代码比较直接:

    代码的实现

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    
    using BLL.Sys;
    
    
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.Text;
    using System.Reflection;
    /// <summary>
    /// LogManager 的摘要说明
    /// </summary>
    public class LogManager<T> where T : new() 
    {
        #region Constructor
        /// <summary>
        /// 日志管理构造函数
        /// </summary>
        public LogManager()
        {
            tableName = typeof(T).Name;
            Model.Sys.LogSetting model = GetLogSetting(tableName);
            if (model != null)
            {
                businessName = model.BusinessName;
                logID = model.LogID;
                primaryKey = model.PrimaryKey;
                urlTemplate = model.UrlTemplate;
                deleteScriptTemplate = model.DeleteScriptTemplate;
                updateScriptTemplate = model.UpdateScriptTemplate;
            }
            else
            {
                throw new ArgumentNullException("日志设置为空!");
            }
        }
        /// <summary>    /// 
        /// 日志管理构造函数
        /// </summary>
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <param name="businessName">业务名称</param>
        public LogManager(string tableName, string businessName)
        {
            this.tableName = tableName;
            this.businessName = businessName;
    
            Model.Sys.LogSetting model = GetLogSetting(tableName, businessName);
            if (model != null)
            {
                logID = model.LogID;
                primaryKey = model.PrimaryKey;
                urlTemplate = model.UrlTemplate;
                deleteScriptTemplate = model.DeleteScriptTemplate;
                updateScriptTemplate = model.UpdateScriptTemplate;
            }
            else
            {
                throw new ArgumentNullException("日志设置为空!");
            }
        }
        #endregion
    
    
        #region Properties
        private int logID;
        private string tableName;
        private string businessName;
        private string primaryKey;
        private string urlTemplate;
        private string deleteScriptTemplate;
        private string updateScriptTemplate;
    
    
        /// <summary>
        /// 日志设置实体列表
        /// </summary>
        public List<Model.Sys.LogSetting> LogSettingList
        {
            get
            {
                System.Web.Caching.Cache cache = HttpRuntime.Cache;
                List<Model.Sys.LogSetting> list = cache["LogSettingList"] as List<Model.Sys.LogSetting>;
                if (list != null && list.Count > 0)
                {
                    return list;
                }
                else
                {
                    LogSetting bll = new LogSetting();
                    list = bll.GetModelList(string.Empty);
                    cache["LogSettingList"] = list;
                    return list;
                }
            }
            set
            {
                System.Web.Caching.Cache cache = HttpRuntime.Cache;
                cache["LogSettingList"] = null;
            }
        }
        /// <summary>
        /// 日志设置明细
        /// </summary>
        public List<Model.Sys.LogSettingDetail> LogSettingDetail
        {
            get
            {
                System.Web.Caching.Cache cache = HttpRuntime.Cache;
                List<Model.Sys.LogSettingDetail> list = cache["LogSettingDetail"] as List<Model.Sys.LogSettingDetail>;
                if (list != null && list.Count > 0)
                {
                    return list;
                }
                else
                {
                    LogSettingDetail bll = new LogSettingDetail();
                    list = bll.GetModelList(string.Empty);
                    cache["LogSettingDetail"] = list;
                    return list;
                }
            }
            set
            {
                System.Web.Caching.Cache cache = HttpRuntime.Cache;
                cache["LogSettingDetail"] = null;
            }
        }
    
        #endregion
    
        #region Method
        /// <summary>
        /// 通过logId获取日志设置明细
        /// </summary>
        /// <param name="logId">日志设置编号</param>
        /// <returns></returns>
        private List<Model.Sys.LogSettingDetail> GetLogSettingDetails(int logId)
        {
            if (logId == 0)
                throw new ArgumentNullException("LogID为空");
    
            List<Model.Sys.LogSettingDetail> list = new List<Model.Sys.LogSettingDetail>();
            foreach (Model.Sys.LogSettingDetail var in LogSettingDetail)
            {
                if (var.LogID == logId)
                    list.Add(var);
            }
            return list;
        }
        /// <summary>
        /// 通过tableName和businessName来获取日志设置对象
        /// </summary>
        /// <param name="tableName"></param>
        /// <param name="businessName"></param>
        /// <returns></returns>
        private Model.Sys.LogSetting GetLogSetting(string tableName, string businessName)
        {
            foreach (Model.Sys.LogSetting var in LogSettingList)
            {
                if (var.TableName.Equals(tableName, StringComparison.InvariantCultureIgnoreCase) && var.BusinessName.Equals(businessName, StringComparison.InvariantCultureIgnoreCase))
                    return var;
            }
            return null;
        }
        private Model.Sys.LogSetting GetLogSetting(string tableName)
        {
            foreach (Model.Sys.LogSetting var in LogSettingList)
            {
                if (var.TableName.Equals(tableName, StringComparison.InvariantCultureIgnoreCase))
                    return var;
            }
            return null;
        }
    
    
        /// <summary>
        /// 比较两个实体,然后返回实体中每个属性值不同的内容
        /// </summary>
        /// <param name="oldObj"></param>
        /// <param name="newObj"></param>
        /// <returns></returns>
        public string Compare(T oldObj, T newObj)
        {
            Type objTye = typeof(T);
    
            StringBuilder sbResult = new StringBuilder();
            string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";
            tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">旧值</th><th scope=\"col\">新值</th></tr>";
    
            string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td><td>{5}</td></tr>";
    
            List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);
            int i = 1;
    
            foreach (Model.Sys.LogSettingDetail var in list)
            {
                PropertyInfo property = objTye.GetProperty(var.ColumnName);
                if (property != null && !property.IsSpecialName)
                {
                    object o = property.GetValue(oldObj, null);
                    object n = property.GetValue(newObj, null);
                    if (!IsEqual(property.PropertyType, o, n))
                    {
                        sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o, n);
                        i++;
                    }
    
                }
            }
    
            sbResult.Append("</table>");
    
            #region Add Log Record
    
            if (i > 1)
            {
                Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();
                operModel.LogID = logID;
                operModel.OperationType = (int)OperationType.Update;
                operModel.Content = tableHeader + sbResult.ToString();
                operModel.CreateTime = DateTime.Now;
                
                
                if (HttpContext.Current != null)
                    operModel.CreateUser = HttpContext.Current.User.Identity.Name;
                if (!string.IsNullOrEmpty(primaryKey))
                {
                    PropertyInfo p = objTye.GetProperty(primaryKey);
                    object o = p.GetValue(newObj, null);
                    if (o != null)
                    {
                        operModel.PrimaryKeyValue = o.ToString();
    
                        if (urlTemplate.Contains("{0}"))
                            operModel.Url = string.Format(urlTemplate, o.ToString());
                    }
    
                }
                LogOperation operBll = new LogOperation();
                operBll.Add(operModel);
    
            }
            #endregion
    
            return tableHeader + sbResult.ToString();
    
        }
        /// <summary>
        /// 删除实体操作,这里并不是真的删除该实体,而是将删除的操作记录在日志中
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string Delete(T obj)
        {
            Type objTye = typeof(T);
    
    
            StringBuilder sbResult = new StringBuilder();
            string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";
            tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">值</th></tr>";
    
            string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>";
    
            List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);
            int i = 1;
            foreach (Model.Sys.LogSettingDetail var in list)
            {
                PropertyInfo property = objTye.GetProperty(var.ColumnName);
                if (property != null && !property.IsSpecialName)
                {
                    object o = property.GetValue(obj, null);
    
                    sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o);
                    i++;
                }
            }
    
            sbResult.Append("</table>");
    
    
            #region Add Log Record       
    
            Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();
            operModel.LogID = logID;
            operModel.OperationType = (int)OperationType.Delete;
            operModel.Content = tableHeader + sbResult.ToString();
            operModel.CreateTime = DateTime.Now;
            if (!string.IsNullOrEmpty(primaryKey))
            {
                PropertyInfo p = objTye.GetProperty(primaryKey);
                object o = p.GetValue(obj, null);
                if (o != null)
                {
                    operModel.PrimaryKeyValue = o.ToString();
                    if (urlTemplate.Contains("{0}"))
                        operModel.Url = string.Format(urlTemplate, o.ToString());
                }
            }
            if (HttpContext.Current != null)
                operModel.CreateUser = HttpContext.Current.User.Identity.Name;
            LogOperation operBll = new LogOperation();
            operBll.Add(operModel);
    
            #endregion
            return string.Empty;
        }
        /// <summary>
        /// 添加实体,将添加的操作记录在日志中
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public string Add(T obj)
        {
            Type objTye = typeof(T);
    
    
            StringBuilder sbResult = new StringBuilder();
            string tableHeader = "<table class=\"GridView\" cellspacing=\"0\" rules=\"all\" border=\"1\" id=\"gv\" style=\"border-collapse:collapse;\">";
            tableHeader += "<tr><th scope=\"col\">序号</th><th scope=\"col\">字段</th><th scope=\"col\">名称</th><th scope=\"col\">值</th></tr>";
    
            string tableRow = "<tr class='{0}'><td>{1}</td><td>{2}</td><td>{3}</td><td>{4}</td></tr>";
    
            List<Model.Sys.LogSettingDetail> list = GetLogSettingDetails(logID);
            int i = 1;
            foreach (Model.Sys.LogSettingDetail var in list)
            {
                PropertyInfo property = objTye.GetProperty(var.ColumnName);
                if (property != null && !property.IsSpecialName)
                {
                    object o = property.GetValue(obj, null);
    
                    sbResult.AppendFormat(tableRow, i % 2 == 0 ? "odd" : "even", i, var.ColumnName, var.ColumnText, o);
                    i++;
                }
            }
    
            sbResult.Append("</table>");
    
    
            #region Add Log Record      
    
            Model.Sys.LogOperation operModel = new Model.Sys.LogOperation();
            operModel.LogID = logID;
            operModel.OperationType = (int)OperationType.Add;
            operModel.Content = tableHeader + sbResult.ToString();
            operModel.CreateTime = DateTime.Now;
            if (!string.IsNullOrEmpty(primaryKey))
            {
                PropertyInfo p = objTye.GetProperty(primaryKey);
                object o = p.GetValue(obj, null);
                if (o != null)
                {
                    operModel.PrimaryKeyValue = o.ToString();
                    if (urlTemplate.Contains("{0}"))
                        operModel.Url = string.Format(urlTemplate, o.ToString());
                }
            }
            if (HttpContext.Current != null)
                operModel.CreateUser = HttpContext.Current.User.Identity.Name;
            LogOperation operBll = new LogOperation();
            operBll.Add(operModel);
    
            #endregion
            return string.Empty;
        }
        /// <summary>
        /// 复制一个对象
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public T Clone(T obj)
        {
            Type objTye = typeof(T);
            T model = new T();
            
            PropertyInfo[] properties = objTye.GetProperties();
            foreach (PropertyInfo property in properties)
            {
                if(!property.IsSpecialName)
                {
                    object o = property.GetValue(obj, null);
                    property.SetValue(model, o, null);
                }
                
    
            }
            return model;
        }
    
        private bool IsEqual(Type dataType, object oldObj, object newObj)
        {
            if (oldObj == null && newObj == null)
                return true;
    
            if (dataType == typeof(int))
            {
                return (int)oldObj == (int)newObj;
            }
            else if (dataType == typeof(decimal))
            {
                return (decimal)oldObj == (decimal)newObj;
            }
            else if (dataType == typeof(double))
            {
                return (double)oldObj == (double)newObj;
            }
            else if (dataType == typeof(Guid))
            {
                return (Guid)oldObj == (Guid)newObj;
            }
            else if (dataType == typeof(DateTime))
            {
                return (DateTime)oldObj == (DateTime)newObj;
            }
            else
                return oldObj.Equals(newObj);
    
        }
    
        #region Script Excute
    
        //public int DeleteBusRecode(string primaryKeyValue)
        //{
        //    if (string.IsNullOrEmpty(tableName))
        //        throw new ArgumentException("tableName为空");
        //    if(string.IsNullOrEmpty(primaryKey))
        //        throw new ArgumentException("primaryKey为空");
        //    if (string.IsNullOrEmpty(deleteScriptTemplate))
        //        throw new ArgumentException("deleteScriptTemplate为空");
    
        //    string strSql = string.Format(deleteScriptTemplate, primaryKeyValue);
    
        //    Database db = DatabaseFactory.CreateDatabase();
        //    return 0;
    
            
        //}
        #endregion
    
        #endregion
    
    
    }
    public enum OperationType
    {
        Select = 0,
        Add = 1,
        Update = 2,
        Delete = 3
    }

    使用的场景

    Model文件:

    public class EmployeeModel
    
    {
    
    public int ID{get;set;}
    
    public string Name{get;set;}
    
    …
    
    }
    
    下面介绍如何将系统操作日志集成到你的业务系统中
    添加操作:
    EmployeeBll bll = new EmployeeBll();
    EmployeeModel model = new EmployeeModel();
    /* model 实体经过漫长的 赋值 后… */
    bll.Add(model);    //添加实体
    //添加系统操作记录
    //日志
    LogManager<EmployeeModel> log = new LogManager<EmployeeModel>();
    log.Add(model);
     
    更新操作:
    EmployeeBll bll = new EmployeeBll();
    EmployeeModel model = bll.GetModel(employeeID);
    LogManager<EmployeeModel> log = new LogManager<EmployeeModel>();
    EmployeeModel modelOld = log.Clone(model);   //克隆EmployeeModel实体对象,这个主要是在系统操作日志记录时使用的
     
    /* model 实体又经过漫长的 赋值 后… */
    bll.Update(model);     //更新实体
    //将更新的内容写入系统操作日志中
    log.Compare(modelOld, model);    //原来的实体和赋值后的实体对比,并将更新的内容写入系统操作日志中
     
    删除操作:
    在GridView的RowDeleting事件中获取要删除的实体
    EmployeeBll bll = new EmployeeBll();
    EmployeeModel model = bll.GetModel(employeeID);
    bll.Delete(employeeID);
    LogManager<EmployeeModel> log = new LogManager<EmployeeModel>();
    log.Delete(model);       //实体的内容记录到日志中
  • 相关阅读:
    CQUOJ 10819 MUH and House of Cards
    CQUOJ 9920 Ladder
    CQUOJ 9906 Little Girl and Maximum XOR
    CQUOJ 10672 Kolya and Tandem Repeat
    CQUOJ 9711 Primes on Interval
    指针试水
    Another test
    Test
    二分图匹配的重要概念以及匈牙利算法
    二分图最大匹配
  • 原文地址:https://www.cnblogs.com/Ruiky/p/2411796.html
Copyright © 2011-2022 走看看