|
@@ -1,12 +1,17 @@
|
|
|
-using Aspose.Words;
|
|
|
+using AlibabaCloud.OpenApiClient.Models;
|
|
|
+using Aspose.Words;
|
|
|
using NPOI.HSSF.Record;
|
|
|
+using OASystem.API.OAMethodLib;
|
|
|
using OASystem.Domain.Attributes;
|
|
|
using OASystem.Domain.Entities.Customer;
|
|
|
using OASystem.Infrastructure.Repositories.CRM;
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
using System.Diagnostics;
|
|
|
-using XAct;
|
|
|
using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
|
|
|
+using static OASystem.API.OAMethodLib.JWTHelper;
|
|
|
+using UAParser;
|
|
|
+using System.Collections.Generic;
|
|
|
+using XAct;
|
|
|
|
|
|
namespace OASystem.API.Middlewares
|
|
|
{
|
|
@@ -42,6 +47,64 @@ namespace OASystem.API.Middlewares
|
|
|
if (apiLogAttribute != null)
|
|
|
{
|
|
|
var startTime = DateTime.UtcNow;
|
|
|
+ int portType = 1, userId = 0, id = 0, status = 0;
|
|
|
+ string updatePreData = string.Empty, updateBefData = string.Empty;
|
|
|
+ bool param5Bool = false, param6Bool = false;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ userId = await ReadToken(context);
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(requestBodyText))
|
|
|
+ {
|
|
|
+ object param1 = string.Empty, param2 = string.Empty, param3 = string.Empty, param4 = string.Empty, param5 = string.Empty, param6 = string.Empty;
|
|
|
+ var requestBodyJson = JsonConvert.DeserializeObject<Dictionary<string, object>>(requestBodyText);
|
|
|
+ bool exists1 = requestBodyJson.TryGetValue("portType", out param1);
|
|
|
+ bool exists2 = requestBodyJson.TryGetValue("userId", out param2);
|
|
|
+ bool exists3 = requestBodyJson.TryGetValue("currUserId", out param3);
|
|
|
+ bool exists4 = requestBodyJson.TryGetValue("createUserId", out param4);
|
|
|
+ bool exists5 = requestBodyJson.TryGetValue("id", out param5);
|
|
|
+ bool exists6 = requestBodyJson.TryGetValue("status", out param6);
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(param1.ToString())) int.TryParse(param1.ToString(), out portType);
|
|
|
+
|
|
|
+ //用户Id处理
|
|
|
+ if (userId < 1)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (apiLogAttribute.OperationEnum == OperationEnum.Login)
|
|
|
+ {
|
|
|
+ var number = requestBodyJson?["number"].ToString();
|
|
|
+ if (!string.IsNullOrEmpty(number))
|
|
|
+ {
|
|
|
+ var info = await _sqlSugar.Queryable<Sys_Users>().Where(x => x.IsDel == 0 && x.Number.Equals(number)).FirstAsync();
|
|
|
+ userId = info.Id;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (int.TryParse(param2.ToString(), out userId)) { }
|
|
|
+ else if (int.TryParse(param3.ToString(), out userId)) { }
|
|
|
+ else if (int.TryParse(param4.ToString(), out userId)) { }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //编辑前数据查询;
|
|
|
+ if (param5 != null) if (!string.IsNullOrEmpty(param5.ToString())) param5Bool = int.TryParse(param5.ToString(), out id);
|
|
|
+
|
|
|
+ if (param6 != null) if (!string.IsNullOrEmpty(param6.ToString())) param6Bool = int.TryParse(param6.ToString(), out status);
|
|
|
+
|
|
|
+ if (param6Bool)
|
|
|
+ {
|
|
|
+ // 2 修改
|
|
|
+ if (status == 2) updatePreData = await TableInfoToJson(apiLogAttribute.TableName, id);
|
|
|
+ }
|
|
|
+ else if (param5Bool)
|
|
|
+ {
|
|
|
+ // id > 0 修改
|
|
|
+ if (id > 0) updatePreData = await TableInfoToJson(apiLogAttribute.TableName, id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (JsonException) { }
|
|
|
|
|
|
// 保存原始响应体流
|
|
|
var originalResponseBody = context.Response.Body;
|
|
@@ -53,31 +116,89 @@ namespace OASystem.API.Middlewares
|
|
|
// 调用下一个中间件
|
|
|
await _next(context);
|
|
|
|
|
|
- // 读取响应体内容
|
|
|
- var responseBodyText = await new StreamReader(responseMemoryStream).ReadToEndAsync();
|
|
|
-
|
|
|
// 重置响应体流的位置
|
|
|
responseMemoryStream.Position = 0;
|
|
|
+
|
|
|
+ // 读取响应体内容
|
|
|
+ var responseBodyText = await ReadResponseBody(responseMemoryStream);
|
|
|
+
|
|
|
// 将响应体内容写回原始响应体流
|
|
|
await responseMemoryStream.CopyToAsync(originalResponseBody);
|
|
|
+
|
|
|
+ //修改后数据查询
|
|
|
+ if (param6Bool)
|
|
|
+ {
|
|
|
+ // 2 修改
|
|
|
+ if (status == 2) updateBefData = await TableInfoToJson(apiLogAttribute.TableName, id);
|
|
|
+ }
|
|
|
+ else if (param5Bool)
|
|
|
+ {
|
|
|
+ // id > 0 修改
|
|
|
+ if (id > 0) updateBefData = await TableInfoToJson(apiLogAttribute.TableName, id);
|
|
|
+ }
|
|
|
+ string remoteIp = context.Connection.RemoteIpAddress?.ToString(),
|
|
|
+ location = string.Empty;
|
|
|
+
|
|
|
+ // 检查请求头中的X-Forwarded-For,以获取真实的客户端IP地址
|
|
|
+ if (context.Request.Headers.ContainsKey("X-Forwarded-For"))
|
|
|
+ {
|
|
|
+ remoteIp = context.Request.Headers["X-Forwarded-For"].ToString().Split(',', StringSplitOptions.RemoveEmptyEntries)[0];
|
|
|
+ }
|
|
|
+
|
|
|
+ remoteIp = await GetExternalIp();
|
|
|
+ location = await GetIpLocation(remoteIp);
|
|
|
+
|
|
|
+ string deviceType = string.Empty, browser = string.Empty, os = string.Empty;
|
|
|
+ var userAgent = context.Request.Headers["User-Agent"].FirstOrDefault();
|
|
|
+ if (!string.IsNullOrEmpty(userAgent))
|
|
|
+ {
|
|
|
+ // 解析User-Agent头
|
|
|
+ var parser = Parser.GetDefault();
|
|
|
+ var client = parser.Parse(userAgent);
|
|
|
+
|
|
|
+ // 提取浏览器信息
|
|
|
+ browser = client.UA.Family; // 浏览器名称
|
|
|
+ var browserVersion = client.UA.Major + "." + client.UA.Minor + "." + client.UA.Patch; // 浏览器版本
|
|
|
+ browser += $"({browserVersion})";
|
|
|
+
|
|
|
+ // 提取操作系统信息
|
|
|
+ os = client.OS.Family; // 操作系统名称
|
|
|
+
|
|
|
+ var osVersion = string.Empty; // 操作系统版本
|
|
|
+ if (!string.IsNullOrEmpty(client.OS.Major)) osVersion += client.OS.Major ;
|
|
|
+ if (!string.IsNullOrEmpty(client.OS.Minor)) osVersion += "." + client.OS.Minor;
|
|
|
+ if (!string.IsNullOrEmpty(client.OS.Patch)) osVersion += "." + client.OS.Patch;
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(osVersion)) os += $"({osVersion})";
|
|
|
+
|
|
|
+ // 提取设备信息
|
|
|
+ deviceType = client.Device.Family; // 设备类型,如 'mobile', 'tablet', 'desktop' 等
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// 记录请求结束时间
|
|
|
var endTime = DateTime.UtcNow;
|
|
|
// 计算耗时
|
|
|
var duration = (long)(endTime - startTime).TotalMilliseconds;
|
|
|
|
|
|
- int portType = 1;
|
|
|
-
|
|
|
var logInfo = new Crm_TableOperationRecord() {
|
|
|
TableName = apiLogAttribute.TableName,
|
|
|
PortType = portType,
|
|
|
OperationItem = apiLogAttribute.OperationEnum,
|
|
|
DataId = apiLogAttribute.DataId,
|
|
|
RequestUrl = context.Request.Path,
|
|
|
- RequestParam = requestBodyText,
|
|
|
- ReturnResult = responseBodyText,
|
|
|
+ RemoteIp = remoteIp,
|
|
|
+ Location = location,
|
|
|
+ RequestParam =!string.IsNullOrEmpty(requestBodyText) ? JsonConvert.SerializeObject(requestBodyText) : null,
|
|
|
+ ReturnResult = !string.IsNullOrEmpty(responseBodyText) ? JsonConvert.SerializeObject(requestBodyText) : null,
|
|
|
Elapsed = duration,
|
|
|
Status = context.Response.StatusCode.ToString(),
|
|
|
-
|
|
|
+ CreateUserId = userId,
|
|
|
+ UpdatePreData = updatePreData,
|
|
|
+ UpdateBefData = updateBefData,
|
|
|
+ Browser= browser,
|
|
|
+ Os = os,
|
|
|
+ DeviceType = deviceType,
|
|
|
};
|
|
|
|
|
|
// 存储到数据库
|
|
@@ -85,26 +206,68 @@ namespace OASystem.API.Middlewares
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- // 调用下一个中间件
|
|
|
await _next(context);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private async Task<string> TableInfoToJson(string tableName,int id)
|
|
|
+ {
|
|
|
+ if (_sqlSugar.DbMaintenance.IsAnyTable(tableName))
|
|
|
+ {
|
|
|
+ var info = await _sqlSugar.Queryable<dynamic>(tableName).Where("id=@id", new { id = id }).FirstAsync();
|
|
|
+ return JsonConvert.SerializeObject(info);
|
|
|
+ }
|
|
|
+
|
|
|
+ return string.Empty;
|
|
|
+ }
|
|
|
+
|
|
|
private async Task<string> ReadRequestBody(HttpRequest request)
|
|
|
{
|
|
|
request.EnableBuffering();
|
|
|
|
|
|
- // 读取请求体内容
|
|
|
- using var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true);
|
|
|
- var requestBodyText = await reader.ReadToEndAsync();
|
|
|
+ using var reader = new StreamReader(
|
|
|
+ request.Body,
|
|
|
+ Encoding.UTF8,
|
|
|
+ detectEncodingFromByteOrderMarks: false,
|
|
|
+ bufferSize: 8192,
|
|
|
+ leaveOpen: true
|
|
|
+ );
|
|
|
|
|
|
- // 重置请求体流的位置
|
|
|
+ var body = await reader.ReadToEndAsync();
|
|
|
request.Body.Position = 0;
|
|
|
+ return body;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<string> ReadResponseBody(Stream stream)
|
|
|
+ {
|
|
|
+ using var reader = new StreamReader(
|
|
|
+ stream,
|
|
|
+ Encoding.UTF8,
|
|
|
+ detectEncodingFromByteOrderMarks: false,
|
|
|
+ bufferSize: 8192,
|
|
|
+ leaveOpen: true
|
|
|
+ );
|
|
|
|
|
|
- return requestBodyText;
|
|
|
+ var body = await reader.ReadToEndAsync();
|
|
|
+ stream.Position = 0;
|
|
|
+ return body;
|
|
|
}
|
|
|
|
|
|
|
|
|
+ private async Task<int> ReadToken(HttpContext context)
|
|
|
+ {
|
|
|
+ var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
|
|
|
+
|
|
|
+ // 检查Authorization头是否存在且以"Bearer "开头
|
|
|
+ if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
|
|
|
+ {
|
|
|
+ var authInfo = JwtHelper.SerializeJwt(authHeader);
|
|
|
+ if (authInfo != null) return authInfo.UserId;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
private async Task<string> GetExternalIp()
|
|
|
{
|
|
|
var response = await _httpClient.GetAsync("https://ifconfig.me");
|