zoukankan      html  css  js  c++  java
  • 系统操作日志表单形式构建

    1.概述

         所谓操作日志,就是某人对指定模块的指定对象进行操作的记录,在某种情况下,可能会有显示本次操作对哪些数据字段进行啦了动,或者是操作前后该模型的数据比对情况。针对于这类需求,想要查看某条操作记录具体改动项信息的时候,对于前端来讲,他不需要知道这个对象的具体类型及各个字段的意义的汉字描述,他们只需要循环遍历,将所有的数据拼到一个div容器里即可。后台该如何去设计才能做到最简化的操作那?第一种情况可以用枚举的形式,来标记每种模型的类型,在每次记录日志的时候,可以将当前枚举也记录进去(数据库/nosql),这样的话,在查看每种记录变动的详情时,就可以根据每种类型封装不同的拼接数据的策略,最终以统一的格式返回给前端。但是,这种操作起来并不是很理想,没实现一种模块的操作都要实现对应的表单项拼接策略,显然以后维护起来并不是十分的完美。那么,能不能通过反射的形式来根绝具体的模型名称动态的获取模型类型,并根据具体的类型和json数据来形成对象,从而完成表单项的构建那??答案是:可以的(c#中可以根据Type type = Type.GetType(FullTypeName);类实现)。下面我们就先实现一下获取当前操作模型具体操作操作记录。

    2.需求分析及实现

        1.前端需要展示成这样:

           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.测试结果

       

    力争写最通俗易懂的文章,不添加任何防腐剂~~~
  • 相关阅读:
    2021/3/12
    2021/3/11
    2021/3/10
    2021/3/9
    2021/3/8
    2021/3/5
    2021/3/4
    2021/3/3
    2021/3/2
    2021/3/1
  • 原文地址:https://www.cnblogs.com/diligent-lsh/p/10054818.html
Copyright © 2011-2022 走看看