1
dengjunjie
2025-09-29 d9c99e0480b4910cdb134778dd5c314b35ec4cf2
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_Core/Middlewares/ApiLogMiddleware.cs
@@ -1,10 +1,13 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Org.BouncyCastle.Asn1.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using WIDESEA_Core.Helper;
using WIDESEA_Core.LogHelper;
@@ -31,83 +34,184 @@
        //todo
        public async Task InvokeAsync(HttpContext context)
        {
            //if (AppSettings.app("Middleware", "RequestResponseLog", "Enabled").ObjToBool())
            {
                // è¿‡æ»¤ï¼Œåªæœ‰æŽ¥å£
                if (context.Request.Path.Value.Contains("api"))
                {
                    context.Request.EnableBuffering();
                    //Stream originalBody = context.Response.Body;
            //if (App.ExpDateTime != null)
            //{
            //    if ((DateTime.Now - App.ExpDateTime.GetValueOrDefault()).TotalSeconds > 0)
            //    {
            //        await ReturnExpiredResponse(context, "系统已过期,请联系管理员");
            //        return;
            //    }
            //    //var Hours = (App.ExpDateTime.GetValueOrDefault() - DateTime.Now).TotalHours;
            //    //if (Hours < 72)
            //    //{
            //    //    // è®°å½•警告日志
            //    //    _logger.LogWarning($"系统即将到期,剩余时间:{Hours:F2}小时,到期时间:{App.ExpDateTime.GetValueOrDefault():yyyy-MM-dd HH:mm:ss}");
            //    //    // åœ¨å“åº”头中添加到期提示
            //    //    context.Response.Headers.Add("X-Expiration-Warning",
            //    //        $"系统将在 {Hours:F2} å°æ—¶åŽåˆ°æœŸ ({App.ExpDateTime.GetValueOrDefault():yyyy-MM-dd HH:mm:ss})");
            //    //    // å¦‚果需要直接返回提示信息,取消下面的注释
            //    //    await ReturnExpirationWarningResponse(context, Hours);
            //    //    return;
            //    //}
            //}
            // è¿‡æ»¤ï¼Œåªæœ‰æŽ¥å£
            if (context.Request.Path.Value?.Contains("api") ?? false)
            {
                if (App.ExpDateTime != null)
                {
                    if ((DateTime.Now - App.ExpDateTime.GetValueOrDefault()).TotalSeconds > 0 && !context.Request.Path.Value.Contains("getVierificationCode") && context.Request.Path.Value != "/api/User/login")
                    {
                        await ReturnExpiredResponse(context, "系统已过期,请联系管理员");
                        return;
                    }
                }
                context.Request.EnableBuffering();
                Stream originalBody = context.Response.Body;
                string requestParam = string.Empty;
                string responseParam = string.Empty;
                try
                {
                    (context.RequestServices.GetService(typeof(RequestLogModel)) as RequestLogModel).RequestDate = DateTime.Now;
                    try
                    {
                        // å­˜å‚¨è¯·æ±‚数据
                        //string requestParam = GetRequestData(context);
                        //DateTime beginDate = DateTime.Now;
                        requestParam = RequestDataLog(context);
                        context.Request.Body.Position = 0;
                    }
                    catch { }
                    using MemoryStream ms = new();
                    context.Response.Body = ms;
                        //using var ms = new MemoryStream();
                        //context.Response.Body = ms;
                    await _next(context);
                        await _next(context);
                    try
                    {
                        // å­˜å‚¨å“åº”数据
                        //DateTime endDate = DateTime.Now;
                        //string responseParam = GetResponsetData(context);
                        responseParam = ResponseDataLog(context.Response);
                    }
                    catch { }
                        //context.Response.Body.Position = 0;
                        //await context.Response.Body.CopyToAsync(originalBody);
                        //Logger.WriteApiLog2DB(context,requestParam, beginDate, responseParam, endDate, context.Response.StatusCode == 200 ? LoggerStatus.Success : LoggerStatus.Error);
                    }
                    catch (Exception ex)
                    {
                        // è®°å½•异常
                        _logger.LogError(ex.Message + "" + ex.InnerException);
                    }
                    finally
                    {
                        //context.Response.Body = originalBody;
                    }
                    ms.Position = 0;
                    await ms.CopyToAsync(originalBody);
                    if (!ShouldSkipLogging(context.Request.Path.Value))
                        Logger.Add(requestParam, responseParam);
                }
                //else
                //{
                //    await _next(context);
                //}
            }
            //else
            //{
            //    await _next(context);
            //}
        }
                catch (Exception ex)
                {
                    // è®°å½•异常
        private string GetRequestData(HttpContext context)
        {
            try
            {
                using StreamReader sr = new StreamReader(context.Request.Body);
                string request = JsonConvert.SerializeObject(sr.ReadToEnd()); ;
                context.Request.Body.Position = 0;
                return request;
                }
                finally
                {
                    context.Response.Body = originalBody;
                }
            }
            catch (Exception ex)
            else
            {
                return $"请求参数获取错误,{ex.Message}";
                await _next(context);
            }
        }
        private string GetResponsetData(HttpContext context)
        /// <summary>
        /// è¿”回过期响应
        /// </summary>
        private async Task ReturnExpiredResponse(HttpContext context, string message)
        {
            try
            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
            context.Response.ContentType = "application/json; charset=utf-8";
            context.Response.Headers.ContentType= "application/json; charset=utf-8";
            var json = new WebResponseContent
            {
                using StreamReader sr = new StreamReader(context.Response.Body);
                string response = JsonConvert.SerializeObject(sr.ReadToEnd()); ;
                context.Response.Body.Position = 0;
                return response;
            }
            catch (Exception ex)
                Message = message,
                Code = 500
            };
            var jsonString = JsonConvert.SerializeObject(json);
            await context.Response.WriteAsync(jsonString);
        }
        /// <summary>
        /// è¿”回到期警告响应(可选)
        /// </summary>
        private async Task ReturnExpirationWarningResponse(HttpContext context, double hoursRemaining)
        {
            context.Response.StatusCode = (int)HttpStatusCode.OK;
            context.Response.ContentType = "application/json";
            var expirationDate = App.ExpDateTime.GetValueOrDefault();
            var response = new
            {
                return $"响应参数获取错误,{ex.Message}";
                Code = 200,
                Message = "系统即将到期警告",
                Data = new
                {
                    HoursRemaining = hoursRemaining,
                    ExpirationDate = expirationDate,
                    FormattedMessage = $"系统将在 {Math.Ceiling(hoursRemaining)} å°æ—¶åŽåˆ°æœŸï¼Œåˆ°æœŸæ—¶é—´ï¼š{expirationDate:yyyy-MM-dd HH:mm:ss}。请联系管理员续期。"
                },
                Warning = true
            };
            var jsonString = JsonConvert.SerializeObject(response);
            await context.Response.WriteAsync(jsonString);
        }
        /// <summary>
        /// åˆ¤æ–­æ˜¯å¦è·³è¿‡æ—¥å¿—记录
        /// </summary>
        private bool ShouldSkipLogging(string path)
        {
            if (string.IsNullOrEmpty(path)) return false;
            var skipKeywords = new[] { "get", "Get", "query", "Query", "DownLoadApp", "downLoadApp", "UploadApp", "uploadApp" };
            return skipKeywords.Any(keyword => path.Contains(keyword, StringComparison.OrdinalIgnoreCase));
        }
        private string RequestDataLog(HttpContext context)
        {
            var request = context.Request;
            var sr = new StreamReader(request.Body);
            object obj;
            string bodyData = sr.ReadToEndAsync().Result;
            if (request.ContentLength <= 100000)
            {
                obj = new
                {
                    QueryString = request.QueryString.ToString(),
                    BodyData = bodyData
                };
            }
            else
            {
                obj = new
                {
                    QueryString = request.QueryString.ToString(),
                    BodyData = ""
                };
            }
            string data = JsonConvert.SerializeObject(obj);
            request.Body.Position = 0;
            return data;
        }
        private string ResponseDataLog(HttpResponse response)
        {
            if (response.ContentLength <= 100000)
            {
                response.Body.Position = 0;
                using StreamReader stream = new StreamReader(response.Body, leaveOpen: true);
                string body = stream.ReadToEnd();
                response.Body.Position = 0;
                return body;
            }
            return "";
        }
    }
}