schangxiang@126.com
2024-09-04 9242d0da6005e070b0197a26b12ba24d1361466d
1
2
3
4
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
using Furion;
using Furion.EventBus;
using Furion.FriendlyException;
using Furion.JsonSerialization;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
using System.Security.Claims;
using UAParser;
 
namespace iWare.Wms.Core
{
    /// <summary>
    /// 请求日志拦截
    /// </summary>
    public class RequestActionFilter : IAsyncActionFilter
    {
        private readonly IEventPublisher _eventPublisher;
 
        public RequestActionFilter(IEventPublisher eventPublisher)
        {
            _eventPublisher = eventPublisher;
        }
 
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var httpContext = context.HttpContext;
            var httpRequest = httpContext.Request;
            
            //获取head信息
            //
            //var headrparam= httpContext.head
 
            var sw = new Stopwatch();
            sw.Start();
            var actionContext = await next();
            sw.Stop();
 
            // 判断是否请求成功(没有异常就是请求成功)
            var isRequestSucceed = actionContext.Exception == null;
            var headers = httpRequest.Headers;
            var clientInfo = headers.ContainsKey("User-Agent") ? Parser.GetDefault().Parse(headers["User-Agent"]) : null;
            var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
            if (headers["AppVersion"].Count ==1 && headers["AppVersion"]!= App.Configuration["AppVersion:Version"] && headers["IsDevelopment"] == "true")
            {
                throw Oops.Oh("请更新PDA版本信息");
            }
            var ip = httpContext.GetRequestIPv4();
 
            //判断是否需有禁用操作日志属性
            foreach (var metadata in actionDescriptor.EndpointMetadata)
            {
                if (metadata.GetType() == typeof(DisableOpLogAttribute))
                {
                    //禁用操作日志,直接返回
                    return;
                }
            }
            await _eventPublisher.PublishAsync(new ChannelEventSource("Create:OpLog",
                new SysLogOp
                {
                    Name = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_NAME),
                    Success = isRequestSucceed ? YesOrNot.Y : YesOrNot.N,
                    Ip = ip,
                    Location = httpRequest.GetRequestUrlAddress(),
                    Browser = clientInfo?.UA.Family + clientInfo?.UA.Major,
                    Os = clientInfo?.OS.Family + clientInfo?.OS.Major,
                    Url = httpRequest.Path,
                    ClassName = context.Controller.ToString(),
                    MethodName = actionDescriptor?.ActionName,
                    ReqMethod = httpRequest.Method,
                    Param = context.ActionArguments.Count < 1 ? string.Empty : JSON.Serialize(context.ActionArguments),
                    Result = actionContext.Result?.GetType() == typeof(JsonResult) ? JSON.Serialize(actionContext.Result) : string.Empty,
                    ElapsedTime = sw.ElapsedMilliseconds,
                    OpTime = DateTimeOffset.Now,
                    Account = httpContext.User?.FindFirstValue(ClaimConst.CLAINM_ACCOUNT)
                }));
        }
 
        /// <summary>
        /// 异常返回值
        /// </summary>
        /// <param name="context"></param>
        /// <param name="metadata"></param>
        /// <returns></returns>
        public IActionResult OnException(ExceptionContext context, ExceptionMetadata metadata)
        {
            return new JsonResult(new XnRestfulResult<object>
            {
                Code = metadata.StatusCode,
                Success = false,
                Data = null,
                Message = metadata.Errors,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }
    }
}