Blame view

web/WebMvc/Aop/OperLogFilter.cs 5.07 KB
赖素文 authored
1
2
3
using Hh.Mes.Common.config;
using Hh.Mes.Common.Json;
using Hh.Mes.Service.Configure;
4
using Hh.Mes.Service.Logs;
赖素文 authored
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using Hh.Mes.Service.SystemAuth;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Net.Http.Headers;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;

namespace WebMvc.Aop
{
    /// <summary>
    ///  操作记录日志
    ///  action 请求前,请求后 
    /// </summary>
    public class OperLogFilter : ActionFilterAttribute
    {
        #region  property
        /// <summary>
        /// action 请求参数
        /// </summary>
        private string actionArguments { get; set; }

        private Stopwatch Stopwatch { get; set; }

        /// <summary>
        /// ioc 数据库访问层注入
        /// </summary>
36
        private readonly LogService _app;
赖素文 authored
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

        /// <summary>
        /// action操作 标识 (新增,删除,编辑,上传等等)
        /// </summary>
        private static Dictionary<string, string> operType { get; set; }

        /// <summary>
        /// 请求体上下文
        /// </summary>
        private HttpContext httpContext { get; set; }

        /// <summary>
        /// 用户信息
        /// </summary>
        private AuthStrategyContext currentUser { get; set; }

        #endregion
55
        public OperLogFilter(LogService  logService, IAuth authUtil)
赖素文 authored
56
        {
57
            _app = logService;
赖素文 authored
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
            operType = ConfigRead.GetInstance.GetOperType();
            currentUser = authUtil.GetCurrentUser();
        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);
            Stopwatch = new Stopwatch();
            Stopwatch.Start();
            httpContext = context.HttpContext;
            actionArguments = JsonConvert.SerializeObject(context.ActionArguments).Replace("\r", "").Replace("\n", "");
        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            base.OnActionExecuted(context);
            Stopwatch.Stop();
            //Net Core 2.1Filter里面获取ControllerAction,请求方法,请求头部,请求参数
            //https://blog.csdn.net/mango_love/article/details/84992020
            var description = (ControllerActionDescriptor)context.ActionDescriptor;
            var actionName = description.ActionName;
            var otype = operType.ContainsKey(actionName) ? operType[actionName] : "其他";
            dynamic response;
            if (context.HttpContext.Request.Method.ToLower() == "get")
            {
83
84
85
86
87
88
89
90
91
                if (otype == "查看")
                {
                    response = "";
                }
                else
                {
                    var temp = context.Result as ObjectResult;
                    response = IsPropertyExist(temp, "Value") ? temp.Value : "在返回结果后发生了异常Get";
                }
赖素文 authored
92
            }
93
            else
赖素文 authored
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
            {
                dynamic result = context.Result;
                response = IsPropertyExist(result, "Value") ? result.Value : "在返回结果前发生了异常";
            }
            InserSysoperLog(otype, response, Stopwatch.Elapsed.TotalSeconds);
        }

        #region 自定义方法
        /// <summary>
        /// 写入日志 异步
        /// </summary>
        private void InserSysoperLog(string otype, dynamic response, double TotalSeconds)
        {
            bool isOk = response is string;
            if (!isOk) response = JsonHelper.Instance.Serialize(response);

            string url = httpContext.Request.Host + httpContext.Request.Path + httpContext.Request.QueryString;
            var dc = new Dictionary<string, object>
            {
                {"url", url},
                {"operType", otype},
                {"method", httpContext.Request.Method},
                {"request",httpContext.Request.Headers[HeaderNames.UserAgent].ToString()},
                {"parameter", actionArguments},

                {"response", response},
                {"totalMilliseconds", TotalSeconds},
                {"logTime", DateTime.Now},
                {"name", currentUser.User.Name},
                {"ip", httpContext.Connection.RemoteIpAddress.ToString()},
                {"createTime", DateTime.Now},
                {"createBy", currentUser.User.Account}
            };
            //字典 异步写入日志
            _app.GetContext().Insertable(dc).AS("sys_oper_log").ExecuteCommandAsync();
        }

        /// <summary>
        /// 动态类型 dynamic 是否存在某个属性
        /// </summary>
        public static bool IsPropertyExist(dynamic data, string propertyname)
        {
            if (data == null)
                return false;
            if (data is ExpandoObject)
                return ((IDictionary<string, object>)data).ContainsKey(propertyname);
            return data.GetType().GetProperty(propertyname) != null;
        } 
        #endregion
    }
}