系統操做日誌表單形式構建

1.概述

     所謂操做日誌,就是某人對指定模塊的指定對象進行操做的記錄,在某種狀況下,可能會有顯示本次操做對哪些數據字段進行啦了動,或者是操做先後該模型的數據比對狀況。針對於這類需求,想要查看某條操做記錄具體改動項信息的時候,對於前端來說,他不須要知道這個對象的具體類型及各個字段的意義的漢字描述,他們只須要循環遍歷,將全部的數據拼到一個div容器裏便可。後臺該如何去設計才能作到最簡化的操做那?第一種狀況能夠用枚舉的形式,來標記每種模型的類型,在每次記錄日誌的時候,能夠將當前枚舉也記錄進去(數據庫/nosql),這樣的話,在查看每種記錄變更的詳情時,就能夠根據每種類型封裝不一樣的拼接數據的策略,最終以統一的格式返回給前端。可是,這種操做起來並非很理想,沒實現一種模塊的操做都要實現對應的表單項拼接策略,顯然之後維護起來並非十分的完美。那麼,能不能經過反射的形式來根絕具體的模型名稱動態的獲取模型類型,並根據具體的類型和json數據來造成對象,從而完成表單項的構建那??答案是:能夠的(c#中能夠根據Type type = Type.GetType(FullTypeName);類實現)。下面咱們就先實現一下獲取當前操做模型具體操做操做記錄。前端

2.需求分析及實現

    1.前端須要展現成這樣:sql

       2.後臺代碼設置數據庫

     

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace ConsoleApp1.OpearorLog.Entity
 9 {
10     public class ColumnRenark : Attribute
11     {
12         /// <summary>
13         /// 字段名稱
14         /// </summary>
15         public string ColumnName { get; set; }
16         /// <summary>
17         /// 字段類型
18         /// </summary>
19         public ColumnType ColumnType { get; set; }
20 
21 
22         public ColumnRenark() { }
23     }
24     public enum ColumnType
25     {
26         [Description("基礎類型(int/string...)")]
27         Basic = 0,
28         [Description("類類型")]
29         Class = 1,
30         [Description("字典類型")]
31         Dic = 2,
32         [Description("列表類型")]
33         Lst = 3,
34 
35 
36     }
37 }
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1.OpearorLog.Entity
{
    /// <summary>
    ///行記錄
    /// </summary>
    public class RowRecord
    {
        /// <summary>
        /// 字段語義
        /// </summary>
        public string Key { get; set; }
        /// <summary>
        /// 字段對應值
        /// </summary>
        public string Value { get; set; }
        /// <summary>
        /// 所屬層級
        /// </summary>
        public int Lev { get; set; }
        /// <summary>
        /// 包含的子項
        /// </summary>
        public List<List<RowRecord>> Child { get; set; }

        public RowRecord()
        {
            Child = new List<List<RowRecord>>();
        }

    }
}
View Code
  1 using Newtonsoft.Json;
  2 using System;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Runtime.InteropServices;
  6 using System.Text;
  7 using System.Threading.Tasks;
  8 
  9 namespace ConsoleApp1
 10 {
 11   public  class OperatorLogContext
 12     {
 13         #region attr
 14         private List<RowRecord> RowRecords { get; set; }
 15         private object Obj { get; set; }
 16         public string FullTypeName { get; set; }
 17         public string JsonStr { get; set; }
 18         #endregion
 19 
 20         public OperatorLogContext(string fullTypeName,string jsonStr)
 21         {
 22             FullTypeName = fullTypeName;
 23             JsonStr = jsonStr;
 24             RowRecords = new List<RowRecord>();
 25             Type type = Type.GetType(FullTypeName);
 26             Obj = JsonConvert.DeserializeObject(JsonStr,type);
 27         }
 28         public OperatorLogContext()
 29         {
 30             Type type = Type.GetType(FullTypeName);
 31             Obj = JsonConvert.DeserializeObject(JsonStr, type);
 32         }
 33         /// <summary>
 34         /// 構建表單項
 35         /// </summary>
 36         /// <returns></returns>
 37         public List<RowRecord> BuildForm()
 38         {
 39             return Build(Obj);
 40         }
 41         #region private
 42         private List<RowRecord> Build(object obj, RowRecord parentRow = null, List<RowRecord> childRow = null, int lev = 0)
 43         {
 44             //1.當前類型
 45             Type currentType = obj.GetType();
 46             //2.獲取當下模型的全部屬性字段
 47             var props = currentType.GetProperties();
 48             foreach (var prop in props)
 49             {
 50                 RowRecord rowRecord = new RowRecord();
 51                 rowRecord.Lev = lev;   //設置當前樹形級別
 52                 //3.獲取當下屬性字段下的全部自定義屬性
 53                 var attr = prop.CustomAttributes.FirstOrDefault(o => o.AttributeType == typeof(ColumnRenark));
 54                 if (attr == null)
 55                 {
 56                     continue;
 57                 }
 58                 else
 59                 {
 60                     foreach (var named in attr.NamedArguments)
 61                     {
 62                         if (named.MemberName == "ColumnName")
 63                         {
 64                             rowRecord.Key = named.TypedValue.Value.ToString();
 65                         }
 66                         else if (named.MemberName == "ColumnType")
 67                         {
 68                             ColumnType columnType = (ColumnType)Enum.Parse(typeof(ColumnType), named.TypedValue.Value.ToString());
 69                             switch (columnType)
 70                             {
 71                                 case ColumnType.Basic:
 72                                     rowRecord.Value = prop.GetValue(obj).ToString();
 73                                     break;
 74                                 case ColumnType.Class:
 75                                     Build(prop.GetValue(obj), rowRecord, new List<RowRecord>());
 76                                     break;
 77                                 case ColumnType.Lst:
 78                                     var currentLst = (IEnumerable<object>)prop.GetValue(obj);
 79 
 80                                     foreach (var opt in currentLst)
 81                                     {
 82 
 83                                         Build(opt, rowRecord, new List<RowRecord>());
 84                                     }
 85                                     break;
 86                             }
 87                         }
 88                     }
 89                 }
 90 
 91                 if (parentRow != null)
 92                 {
 93                     rowRecord.Lev = parentRow.Lev + 1;
 94                     childRow.Add(rowRecord);
 95                 }
 96                 else
 97                 {
 98                     RowRecords.Add(rowRecord);
 99                 }
100             }
101             if (childRow != null)
102             {
103                 parentRow.Child.Add(childRow);
104             }
105             return RowRecords;
106         }
107         #endregion
108 
109     }
110 }
View Code
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User();
            user.Age = 20;
            user.Name = "lsh";
            user.Book = new Book()
            {
                Name = "c#從入門指南",
                Desc = "書籍描述"
            };
            user.Hobby = new List<Hobby>() {
                new Hobby() { Name = "讀書", Rate = "89%" },
                new Hobby() { Name = "旅遊", Rate = "33%" }
            };
            string json = JsonConvert.SerializeObject(user);
            var lst = new OperatorLogContext("ConsoleApp1.User", json).BuildForm();
            Console.ReadKey();
        }
    }
    public class User
    {
        [ColumnRenark(ColumnName = "姓名", ColumnType = ColumnType.Basic)]
        public string Name { get; set; }
        [ColumnRenark(ColumnName = "年齡", ColumnType = ColumnType.Basic)]
        public int Age { get; set; }
        [ColumnRenark(ColumnName = "書籍", ColumnType = ColumnType.Class)]
        public Book Book { get; set; }
        [ColumnRenark(ColumnName = "愛好", ColumnType = ColumnType.Lst)]
        public List<Hobby> Hobby { get; set; }

    }
    public class Hobby
    {
        [ColumnRenark(ColumnName = "愛好名", ColumnType = ColumnType.Basic)]
        public string Name { get; set; }
        [ColumnRenark(ColumnName = "比率", ColumnType = ColumnType.Basic)]
        public string Rate { get; set; }
    }
    /// <summary>
    /// 行元素
    /// </summary>
    public class RowRecord
    {
        public string Key { get; set; }
        public string Value { get; set; }
        public int Lev { get; set; }
        public List<List<RowRecord>> Child { get; set; }

        public RowRecord()
        {
            Child = new List<List<RowRecord>>();
        }
    }
    public class Book
    {
        [ColumnRenark(ColumnName = "書名", ColumnType = ColumnType.Basic)]
        public string Name { get; set; }
        [ColumnRenark(ColumnName = "書描述", ColumnType = ColumnType.Basic)]
        public string Desc { get; set; }
    }
    /// <summary>
    /// 字段標記屬性
    /// </summary>
    public class ColumnRenark : Attribute
    {
        /// <summary>
        /// 字段名稱
        /// </summary>
        public string ColumnName { get; set; }
        /// <summary>
        /// 字段類型
        /// </summary>
        public ColumnType ColumnType { get; set; }


        public ColumnRenark() { }
    }

    public enum ColumnType
    {
        [Description("基礎類型(int/string...)")]
        Basic = 0,
        [Description("類類型")]
        Class = 1,
        [Description("字典類型")]
        Dic = 2,
        [Description("列表類型")]
        Lst = 3,


    }
}
View Code

3.測試結果

   

相關文章
相關標籤/搜索