diff --git a/src/InterfaceForward.Api/InterfaceForward.Api.csproj b/src/InterfaceForward.Api/InterfaceForward.Api.csproj
index b3a6390..51a3bbe 100644
--- a/src/InterfaceForward.Api/InterfaceForward.Api.csproj
+++ b/src/InterfaceForward.Api/InterfaceForward.Api.csproj
@@ -16,11 +16,11 @@
-
+
-
+
-
+
diff --git a/src/InterfaceForward.Api/InterfaceForwardApiModule.cs b/src/InterfaceForward.Api/InterfaceForwardApiModule.cs
index dc1460f..4f52e70 100644
--- a/src/InterfaceForward.Api/InterfaceForwardApiModule.cs
+++ b/src/InterfaceForward.Api/InterfaceForwardApiModule.cs
@@ -1,17 +1,13 @@
using Fake.AspNetCore;
-using Fake.AspNetCore.Mvc;
+using Fake.AspNetCore.Auditing;
using Fake.AspNetCore.Mvc.Conventions;
-using Fake.Authorization;
using Fake.Autofac;
using Fake.Modularity;
using InterfaceForward.Application;
-using InterfaceForward.Application.Filters;
-using Microsoft.AspNetCore.Mvc;
namespace InterfaceForward.Api;
[DependsOn(typeof(FakeAutofacModule))]
-[DependsOn(typeof(FakeAspNetCoreMvcModule))]
[DependsOn(typeof(InterfaceForwardApplicationModule))]
public class InterfaceForwardApiModule : FakeModule
{
@@ -23,20 +19,16 @@ public class InterfaceForwardApiModule : FakeModule
// Add services to the container.
services.AddProblemDetails();
-
- services.Configure(options =>
- {
- options.Filters.AddService();
- options.Filters.AddService();
- });
-
+
services.Configure(options =>
{
options.AddAssembly(typeof(InterfaceForwardApplicationModule).Assembly);
});
-
- services.AddUnifiedResultFilter();
- services.AddFakeSwaggerGen();
+
+ services.AddFakeSwaggerGen()
+ .AddFakeExceptionFilter()
+ .AddFakeValidationActionFilter()
+ .AddFakeAspNetCoreAuditing();
services.AddCors(options =>
{
@@ -54,11 +46,9 @@ public class InterfaceForwardApiModule : FakeModule
{
var app = context.GetWebApplication();
- app.MapControllers();
-
// Add Aspire default endpoints.
app.MapDefaultEndpoints();
-
+ app.MapControllers();
// Configure the HTTP request pipeline.
app.UseFakeSwagger();
@@ -66,16 +56,4 @@ public class InterfaceForwardApiModule : FakeModule
app.UseCors(DefaultCorsPolicyName);
}
-}
-
-public static class ServiceCollectionExtensions
-{
- public static IServiceCollection AddSwagger(this IServiceCollection services)
- {
- // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
- services.AddEndpointsApiExplorer();
- services.AddSwaggerGen();
-
- return services;
- }
}
\ No newline at end of file
diff --git a/src/InterfaceForward.Api/Logs/SerilogHostingExtensions.cs b/src/InterfaceForward.Api/Logs/SerilogHostingExtensions.cs
deleted file mode 100644
index d7b8bb7..0000000
--- a/src/InterfaceForward.Api/Logs/SerilogHostingExtensions.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-
-using InterfaceForward.Domain.Shared.Options;
-using InterfaceForward.Repositories.Log;
-using Serilog;
-
-namespace InterfaceForward.Api.Logs;
-
-public static class SerilogHostingExtensions
-{
- public static WebApplicationBuilder UseSerilogDefault(this WebApplicationBuilder builder)
- {
- var configuration = builder.Configuration;
-
- Log.Logger = new LoggerConfiguration()
- .ReadFrom.Configuration(configuration)
- .CreateLogger();
-
- //初始化配置
- var environment = configuration["Environment"];
- var options = configuration.GetSection("Notice")?.Get();
- if (options == null)
- Console.Write("-- 未找到日志飞书通知相关配置");
- else
- LogHelper.Init(options, environment == "uat" || environment == "Product");//写死了
-
- builder.Host.UseSerilog();
- return builder;
- }
-}
\ No newline at end of file
diff --git a/src/InterfaceForward.Api/Program.cs b/src/InterfaceForward.Api/Program.cs
index edbdf93..a5d6a02 100644
--- a/src/InterfaceForward.Api/Program.cs
+++ b/src/InterfaceForward.Api/Program.cs
@@ -1,13 +1,16 @@
using InterfaceForward.Api;
-using InterfaceForward.Api.Logs;
using Serilog;
+var builder = WebApplication.CreateSlimBuilder(args);
+var configuration = builder.Configuration;
+Log.Logger = new LoggerConfiguration()
+ .ReadFrom.Configuration(configuration)
+ .CreateLogger();
+
try
{
- var builder = WebApplication.CreateSlimBuilder(args);
- builder.UseSerilogDefault();
builder.WebHost.UseUrls(builder.Configuration.GetSection("App:Urls").Get() ?? []);
- builder.Host.UseAutofac();
+ builder.Host.UseAutofac().UseSerilog();
builder.Services.AddApplication();
// Add service defaults & Aspire components.
diff --git a/src/InterfaceForward.Api/appsettings.json b/src/InterfaceForward.Api/appsettings.json
index 91fe569..a3c9a1e 100644
--- a/src/InterfaceForward.Api/appsettings.json
+++ b/src/InterfaceForward.Api/appsettings.json
@@ -26,5 +26,9 @@
"CorsOrigins": [
"http://localhost:8888"
]
+ },
+ "FeiShuNotice": {
+ "Title": "InterfaceForward-Dev",
+ "Webhook": "https://open.feishu.cn/open-apis/bot/v2/hook/255c44ff-5891-4902-9b6a-6d0250e745f7"
}
}
diff --git a/src/InterfaceForward.Application.Contracts/ForwardCore/InterfaceRelayUnifyResultDto.cs b/src/InterfaceForward.Application.Contracts/ForwardCore/InterfaceRelayUnifyResultDto.cs
index eb3fd9f..2267827 100644
--- a/src/InterfaceForward.Application.Contracts/ForwardCore/InterfaceRelayUnifyResultDto.cs
+++ b/src/InterfaceForward.Application.Contracts/ForwardCore/InterfaceRelayUnifyResultDto.cs
@@ -3,13 +3,18 @@
namespace InterfaceForward.Application.Contracts.ForwardCore;
[Serializable]
-public class InterfaceRelayUnifyResultDto : UnifyResultDto
+public class InterfaceRelayUnifyResultDto
{
///
/// 请求Id
///
public Guid RequestId { get; set; }
+ ///
+ /// 消息
+ ///
+ public string? Message { get; set; }
+
///
/// 原报文
///
diff --git a/src/InterfaceForward.Application/AutoMapper/AppProfile.cs b/src/InterfaceForward.Application/AutoMapper/AppProfile.cs
index abf5eb7..7be97a3 100644
--- a/src/InterfaceForward.Application/AutoMapper/AppProfile.cs
+++ b/src/InterfaceForward.Application/AutoMapper/AppProfile.cs
@@ -2,15 +2,14 @@
using InterfaceForward.Application.Contracts.Dtos.App;
using InterfaceForward.Repositories.App.Entitys;
-namespace InterfaceForward.Application.AutoMapper
+namespace InterfaceForward.Application.AutoMapper;
+
+internal class AppProfile : Profile
{
- internal class AppProfile : Profile
+ public AppProfile()
{
- public AppProfile()
- {
- CreateMap(MemberList.None);
- CreateMap(MemberList.None);
- CreateMap(MemberList.None);
- }
+ CreateMap(MemberList.None);
+ CreateMap(MemberList.None);
+ CreateMap(MemberList.None);
}
-}
+}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/DisableRequestLogAttribute.cs b/src/InterfaceForward.Application/Filters/DisableRequestLogAttribute.cs
deleted file mode 100644
index 3e530cb..0000000
--- a/src/InterfaceForward.Application/Filters/DisableRequestLogAttribute.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace InterfaceForward.Application.Filters;
-
-public class DisableRequestLogAttribute:Attribute;
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/ForwardAuthorizeFilter.cs b/src/InterfaceForward.Application/Filters/ForwardAuthorizeFilter.cs
index 626b3f3..fd90df3 100644
--- a/src/InterfaceForward.Application/Filters/ForwardAuthorizeFilter.cs
+++ b/src/InterfaceForward.Application/Filters/ForwardAuthorizeFilter.cs
@@ -1,7 +1,7 @@
using System.Text;
+using Fake.AspNetCore.Http;
using InterfaceForward.Repositories;
using InterfaceForward.Repositories.Log.Services;
-using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
@@ -9,43 +9,24 @@ using Newtonsoft.Json;
namespace InterfaceForward.Application.Filters;
-public class ForwardAuthorizeFilter : IAsyncActionFilter
+public class ForwardAuthorizeFilter(
+ InterfaceForwardQuery interfaceForwardQuery,
+ ILogRepository logRepository,
+ IHttpClientInfoProvider httpClientInfoProvider)
+ : IAsyncActionFilter
{
- private readonly InterfaceForwardQuery _interfaceForwardQuery;
- private readonly ILogRepository _logRepository;
-
- private readonly IHttpContextAccessor _httpContextAccessor;
- // private readonly IEntrySegmentContextAccessor _segContext;
-
- public ForwardAuthorizeFilter(
- InterfaceForwardQuery interfaceForwardQuery
- // , IEntrySegmentContextAccessor segContext
- , ILogRepository logRepository
- , IHttpContextAccessor httpContextAccessor)
- {
- _interfaceForwardQuery = interfaceForwardQuery;
- _logRepository = logRepository;
- _httpContextAccessor = httpContextAccessor;
- // _segContext = segContext;
- }
-
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var start = DateTime.Now;
// _segContext.Context.Span.AddLog(LogEvent.Message("进入授权过滤器"));
- var log = _logRepository.AppRequestLog;
+ var log = logRepository.AppRequestLog;
log.RequestTime = start;
var httpContext = context.HttpContext;
log.IsApp = true;
- var ip = _httpContextAccessor.HttpContext!.Connection.RemoteIpAddress?.MapToIPv4().ToString();
- if (_httpContextAccessor.HttpContext.Request.Headers.TryGetValue("X-Forwarded-For", out var header))
- {
- ip = header.ToString();
- }
- log.ClientIP = ip;
+ log.ClientIp = httpClientInfoProvider.ClientIpAddress;
log.Address = httpContext.Request.GetDisplayUrl();
// body
@@ -66,20 +47,16 @@ public class ForwardAuthorizeFilter : IAsyncActionFilter
throw new BusinessException(message: "应用授权失败,AppKey和AppSecret是必填的");
}
- var app = await _interfaceForwardQuery.FindAppAsync(appKey, appSecret);
+ var app = await interfaceForwardQuery.FindAppAsync(appKey!, appSecret!);
if (app == null)
throw new BusinessException(message: "应用授权失败,请检查AppKey或AppSecret是否正确");
log.Name = app.Name;
if (!app.IsOnline)
throw new BusinessException(message: "应用已被禁用,请检查应用状态");
- _logRepository.AppId = app.Id;
+ logRepository.AppId = app.Id;
- // await InterfaceLimitAsync(httpContext, app.Id);
-
- // _segContext.Context.Span.AddLog(LogEvent.Message("开始执行action"));
var actionContext = await next();
- // _segContext.Context.Span.AddLog(LogEvent.Message("action执行完毕"));
if (actionContext.Exception == null)
{
@@ -91,10 +68,10 @@ public class ForwardAuthorizeFilter : IAsyncActionFilter
}
else
{
- log.Response = actionContext.Result?.ToString();
+ log.Response = actionContext.Result?.ToString()?? string.Empty;
}
- _ = _logRepository.WriteAppLog();
+ _ = logRepository.WriteAppLogAsync();
}
}
}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/ForwardExceptionFilter.cs b/src/InterfaceForward.Application/Filters/ForwardExceptionFilter.cs
deleted file mode 100644
index a41c2f1..0000000
--- a/src/InterfaceForward.Application/Filters/ForwardExceptionFilter.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using InterfaceForward.Application.Contracts;
-using InterfaceForward.Application.Contracts.ForwardCore;
-using InterfaceForward.Repositories.Log.Services;
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.Extensions.Localization;
-using Microsoft.Extensions.Options;
-using Newtonsoft.Json;
-using SJZY.InterfaceRelay.Application.Contracts;
-
-namespace InterfaceForward.Application.Filters;
-
-public class ForwardExceptionFilter(ILogRepository logRepository) : IAsyncExceptionFilter
-{
- public async Task OnExceptionAsync(ExceptionContext context)
- {
- if (context.ExceptionHandled) return;
-
- /*
- * ServiceProviderRequestLog设计的意义是:
- * 最大可能限度的保留请求服务商发生异常时附近的日志信息,以便于排查问题
- */
- var originMessage = bool.TryParse(context.HttpContext.Request.Headers["isReturnMessage"].ToString(),
- out var isReturnMessage)
- ? isReturnMessage ? logRepository.ServiceProviderRequestLog.Response : null
- : null;
-
- var res = new InterfaceRelayUnifyResultDto
- {
- Code = StatusCodes.Status400BadRequest.ToString(),
- RequestId = logRepository.AppRequestLog.RequestId,
- OriginalMessage = originMessage,
- Attach = context.HttpContext.Request.Headers["attach"]
- };
- if (context.Exception is BusinessException business) //业务异常
- {
- res.Code = string.IsNullOrEmpty(business.Code) ? StatusCodes.Status400BadRequest.ToString() : business.Code;
- res.Message = business.Message;
- context.Result = new JsonResult(res);
- }
- else //未处理异常
- {
- logRepository.SendFeiShu(context.Exception);
- res.Code = StatusCodes.Status500InternalServerError.ToString();
- res.Message = "服务器发生未处理异常!";
- context.Result = new JsonResult(res);
- }
-
- // 异常情况也要记录app日志
- logRepository.AppRequestLog.Response = JsonConvert.SerializeObject(res);
- _ = logRepository.WriteAppLog(context.Exception);
- context.ExceptionHandled = true;
- }
-}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/ForwardExceptionSubscriber.cs b/src/InterfaceForward.Application/Filters/ForwardExceptionSubscriber.cs
new file mode 100644
index 0000000..ed1093a
--- /dev/null
+++ b/src/InterfaceForward.Application/Filters/ForwardExceptionSubscriber.cs
@@ -0,0 +1,55 @@
+using Fake.ExceptionHandling;
+using InterfaceForward.Application.Contracts.ForwardCore;
+using InterfaceForward.Domain.Shared.FeiShu;
+using InterfaceForward.Repositories.Log.Services;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Newtonsoft.Json;
+namespace InterfaceForward.Application.Filters;
+
+public class ForwardExceptionSubscriber : IExceptionSubscriber
+{
+ public Task HandleAsync(ExceptionNotificationContext context)
+ {
+ var httpContext = context.ServiceProvider.GetRequiredService().HttpContext;
+ var logRepository = context.ServiceProvider.GetRequiredService();
+ var feiShuNoticer = context.ServiceProvider.GetRequiredService();
+
+// if (httpContext == null)
+// {
+// feiShuNoticer.NoticeAsync($"""
+// 日志请求id:{ServiceProviderRequestLog.RequestId}
+// 服务商--接口:{ServiceProviderRequestLog.Name}--{ServiceProviderRequestLog.InterfaceName}
+// 异常原因:{Truncate(contextException.ToString())}
+// 请求地址:{ServiceProviderRequestLog.Address}
+// 原始报文:
+// {Truncate(AppRequestLog.Content)}
+// 请求报文:
+// {Truncate(ServiceProviderRequestLog.Content)}
+// 响应报文:
+// {Truncate(ServiceProviderRequestLog.Response)}
+// """)
+// }
+//
+ /*
+ * ServiceProviderRequestLog设计的意义是:
+ * 最大可能限度的保留请求服务商发生异常时附近的日志信息,以便于排查问题
+ */
+ var originMessage = bool.TryParse(httpContext.Request.Headers["isReturnMessage"].ToString(),
+ out var isReturnMessage)
+ ? isReturnMessage ? logRepository.ServiceProviderRequestLog.Response : null
+ : null;
+ var res = new InterfaceRelayUnifyResultDto
+ {
+ RequestId = logRepository.AppRequestLog.RequestId,
+ OriginalMessage = originMessage,
+ Message = context.Exception.Message,
+ Attach = httpContext.Request.Headers["attach"]
+ };
+ logRepository.AppRequestLog.Response = JsonConvert.SerializeObject(res);
+ // 异常情况也要记录app日志
+ _ = logRepository.WriteAppLogAsync(context.Exception);
+
+ return Task.CompletedTask;
+ }
+}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/GlobalExceptionFilter.cs b/src/InterfaceForward.Application/Filters/GlobalExceptionFilter.cs
deleted file mode 100644
index d433c58..0000000
--- a/src/InterfaceForward.Application/Filters/GlobalExceptionFilter.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System.Net;
-using Fake.DependencyInjection;
-using InterfaceForward.Domain.Shared.Dtos;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.Extensions.Hosting;
-
-namespace InterfaceForward.Application.Filters;
-
-public class GlobalExceptionFilter(IHostEnvironment environment) : IAsyncExceptionFilter, ITransientDependency
-{
- public Task OnExceptionAsync(ExceptionContext context)
- {
- if (context.ExceptionHandled) return Task.CompletedTask;
-
- var result = new UnifyResultDto
- {
- Message = context.Exception.Message
- };
- if (environment.IsDevelopment())
- {
- result.Message = context.Exception.ToString();
- }
-
- if (context.Exception is BusinessException) //业务异常
- {
- result.Code = HttpStatusCode.BadRequest.ToString();
- }
- else //未处理异常
- {
- result.Code = HttpStatusCode.InternalServerError.ToString();
- }
-
- context.Result = new JsonResult(result);
- context.ExceptionHandled = true;
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/IgnoreLogDetailAttribute.cs b/src/InterfaceForward.Application/Filters/IgnoreLogDetailAttribute.cs
deleted file mode 100644
index 5b52298..0000000
--- a/src/InterfaceForward.Application/Filters/IgnoreLogDetailAttribute.cs
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace InterfaceForward.Application.Filters
-{
- [AttributeUsage(AttributeTargets.Method)]
- public class IgnoreLogDetailAttribute : Attribute;
-}
diff --git a/src/InterfaceForward.Application/Filters/RequestLogFilter.cs b/src/InterfaceForward.Application/Filters/RequestLogFilter.cs
deleted file mode 100644
index e0a708d..0000000
--- a/src/InterfaceForward.Application/Filters/RequestLogFilter.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-using System.Diagnostics;
-using Fake.DependencyInjection;
-using InterfaceForward.Repositories.Log;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.AspNetCore.Mvc.Filters;
-using Microsoft.AspNetCore.Mvc.ModelBinding;
-using Newtonsoft.Json;
-
-namespace InterfaceForward.Application.Filters;
-
-public class RequestLogFilter : IAsyncActionFilter, ISingletonDependency
-{
-
- public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
- {
- var logInfo = new RequestLogInfo();
- try
- {
- var httpContext = context.HttpContext;
- var httpRequest = httpContext.Request;
- var currentTime = DateTime.Now;
- var requestCode = Guid.NewGuid().ToString("N");
-
- //获取请求参数
- var parameters = context?.ActionDescriptor?.Parameters;
- var paramsterNames = parameters?.Where(x => x.BindingInfo != null && x.BindingInfo.BindingSource != BindingSource.Services)?.Select(x => x.Name)?.ToArray();
- logInfo.RequestParamsters = httpRequest.Method == "GET" ? httpRequest.QueryString.ToString() : JsonConvert.SerializeObject(context?.ActionArguments?.Where(m => paramsterNames.Contains(m.Key)));
- context.HttpContext.Request.Headers.Add(FilterSettingConstant.RequestCode, requestCode);
- context.HttpContext.Request.Headers.Add(FilterSettingConstant.RequestParameters, logInfo.RequestParamsters);
-
- var sw = new Stopwatch();
- sw.Start();
- var actionContext = await next();
- sw.Stop();
-
- // 记录日志
- logInfo.RequestCode = requestCode;
- logInfo.TotalTime = sw.ElapsedMilliseconds;
- logInfo.RequestPath = httpRequest.Path;
- logInfo.ExecuteTime = currentTime;
-
- if (actionContext.Exception != null)
- {
- logInfo.Result = actionContext.Exception.ToString();
- }
- else
- {
- if (!context.ActionDescriptor.EndpointMetadata.Any(m => m.GetType() == typeof(IgnoreLogDetailAttribute)))
- {
- string? exceptionMsg = null;
- if (actionContext.Exception == null)
- {
- if (actionContext.Result is FileResult)
- {
- exceptionMsg = $"...[文件流结果日志已忽略打印]...";
- }
- else
- {
- exceptionMsg = JsonConvert.SerializeObject((actionContext.Result as dynamic)?.Value);
- }
- }
- else
- {
- exceptionMsg = actionContext.Exception.ToString();
- }
- logInfo.Result = exceptionMsg;
- }
- else
- {
- logInfo.Result = $"...[日志已忽略打印]...";
- }
- }
- logInfo.Headers = httpRequest.Headers;
- logInfo.Exception = actionContext.Exception;
-
- }
- catch (Exception ex)
- {
- Console.WriteLine($"记录日志发生未处理异常:{ex}");
- }
- finally
- {
- var log = $@"
- |-请求编号:{logInfo.RequestCode}
- |-消耗时间:{logInfo.TotalTime}毫秒
- |-请求路径:{logInfo.RequestPath}
- |-执行时间:{logInfo.ExecuteTime.ToString("yyyy-MM-dd HH:mm:ss ffff")}
- |-用户信息:{logInfo.UserInfo}
- |-请求参数:{logInfo.RequestParamsters}
- |-执行结果:{logInfo.Result}
- |-Headers:{(logInfo.Headers == null ? "" : JsonConvert.SerializeObject(logInfo.Headers))}";
-
-
- LogHelper.Info(log);
- }
- }
-}
-
-internal static class FilterSettingConstant
-{
- internal const string RequestCode = "SJZY_Request_Code";
- internal const string RequestParameters = "SJZY_Request_Parameter";
- internal const string Authorization = "Authorization";
-}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Filters/RequestLogInfo.cs b/src/InterfaceForward.Application/Filters/RequestLogInfo.cs
deleted file mode 100644
index eca25eb..0000000
--- a/src/InterfaceForward.Application/Filters/RequestLogInfo.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using Microsoft.AspNetCore.Http;
-
-namespace InterfaceForward.Application.Filters;
-
-public struct RequestLogInfo
-{
- ///
- /// 执行时间
- ///
- public DateTime ExecuteTime { get; set; }
-
- ///
- /// 执行时长
- ///
- public long TotalTime { get; set; }
-
- ///
- /// 请求编号
- ///
- public string RequestCode { get; set; }
-
- ///
- /// 请求路径
- ///
- public string RequestPath { get; set; }
-
- ///
- /// 请求参数
- ///
- public string RequestParamsters { get; set; }
-
- ///
- /// 返回结果
- ///
- public dynamic Result { get; set; }
-
- ///
- /// 请求头
- ///
- public IHeaderDictionary Headers { get; set; }
-
- ///
- /// 异常信息
- ///
- public Exception? Exception { get; internal set; }
-
- ///
- /// 用户信息
- ///
- public string UserInfo { get; internal set; }
-}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/ForwardCore/DefaultForwardFlow.cs b/src/InterfaceForward.Application/ForwardCore/DefaultForwardFlow.cs
index 1b8c73d..6fb0ec7 100644
--- a/src/InterfaceForward.Application/ForwardCore/DefaultForwardFlow.cs
+++ b/src/InterfaceForward.Application/ForwardCore/DefaultForwardFlow.cs
@@ -273,9 +273,7 @@ public class DefaultForwardFlow : IForwardFlow
context.ServiceProviderRequestLog.Address = context.TargetInterface.RequestAddress;
context.ServiceProviderRequestLog.IsSuccess = false;
- throw new BusinessException(
- code: code,
- message: msg);
+ throw new BusinessException(message: msg);
}
///
@@ -285,7 +283,7 @@ public class DefaultForwardFlow : IForwardFlow
public virtual void BeforeRequest(ForwardCoreContext context)
{
var log = context.ServiceProviderRequestLog;
- log.ClientIP = NetUtil.GetLanIp();
+ log.ClientIp = NetUtil.GetLanIp();
log.Content = context.TargetInterfaceInput;
context.ServiceProviderRequestLog.RequestTime = DateTime.Now;
@@ -384,7 +382,7 @@ public class DefaultForwardFlow : IForwardFlow
{
if (!await CanVisitInterfaceAsync(context.TargetInterface.Code, qps))
{
- throw new BusinessException("4004", $"服务商接口qps已达到上限{qps},稍后请求");
+ throw new BusinessException($"服务商接口qps已达到上限{qps},稍后请求");
}
}
diff --git a/src/InterfaceForward.Application/InterfaceForward.Application.csproj b/src/InterfaceForward.Application/InterfaceForward.Application.csproj
index 89d1b2b..5f69f77 100644
--- a/src/InterfaceForward.Application/InterfaceForward.Application.csproj
+++ b/src/InterfaceForward.Application/InterfaceForward.Application.csproj
@@ -17,10 +17,9 @@
+
+
-
-
-
diff --git a/src/InterfaceForward.Application/InterfaceForwardApplicationModule.cs b/src/InterfaceForward.Application/InterfaceForwardApplicationModule.cs
index 0d23ed6..7c38515 100644
--- a/src/InterfaceForward.Application/InterfaceForwardApplicationModule.cs
+++ b/src/InterfaceForward.Application/InterfaceForwardApplicationModule.cs
@@ -1,5 +1,5 @@
using System.Security.Authentication;
-using Fake.AspNetCore.Mvc;
+using Fake.AspNetCore;
using Fake.Modularity;
using Fake.ObjectMapping.AutoMapper;
using InterfaceForward.Application.Contracts;
@@ -8,6 +8,7 @@ using Microsoft.Extensions.DependencyInjection;
namespace InterfaceForward.Application;
+[DependsOn(typeof(FakeAspNetCoreModule))]
[DependsOn(typeof(FakeObjectMappingAutoMapperModule))]
[DependsOn(typeof(InterfaceForwardRepositoriesModule))]
public class InterfaceForwardApplicationModule:FakeModule
diff --git a/src/InterfaceForward.Application/Services/App/AppsService.cs b/src/InterfaceForward.Application/Services/App/AppsService.cs
index 5c8ad9e..28ebdb7 100644
--- a/src/InterfaceForward.Application/Services/App/AppsService.cs
+++ b/src/InterfaceForward.Application/Services/App/AppsService.cs
@@ -19,7 +19,7 @@ namespace InterfaceForward.Application.Services.App;
///
[Route("App")]
[ApiExplorerSettings(GroupName = "应用服务")]
-public class AppsService : ApplicationService
+public class AppsService : BaseService
{
private readonly IAppRepository _appRepository;
private readonly IAppScopeRepository _appScopeRepository;
@@ -59,7 +59,7 @@ public class AppsService : ApplicationService
var urlDic = OSSHelper.GetUrlByKeys(logoKeys);
foreach (var url in urlDic)
- res.Items.Find(x => x.LogoKey == url.Key)!.LogoUrl = url.Value;
+ res.Items.First(x => x.LogoKey == url.Key).LogoUrl = url.Value;
return res;
}
diff --git a/src/InterfaceForward.Application/Services/App/DictionaryService.cs b/src/InterfaceForward.Application/Services/App/DictionaryService.cs
index cb3330a..a6437d9 100644
--- a/src/InterfaceForward.Application/Services/App/DictionaryService.cs
+++ b/src/InterfaceForward.Application/Services/App/DictionaryService.cs
@@ -8,7 +8,7 @@ namespace InterfaceForward.Application.Services.App
///
[Route("Dictionary")]
[ApiExplorerSettings(GroupName = "应用服务")]
- public class DictionaryService : ApplicationService
+ public class DictionaryService : BaseService
{
private readonly IDictionaryRepository _dictionaryRepository;
diff --git a/src/InterfaceForward.Application/Services/App/LogService.cs b/src/InterfaceForward.Application/Services/App/LogService.cs
index 26cdd6f..39d3243 100644
--- a/src/InterfaceForward.Application/Services/App/LogService.cs
+++ b/src/InterfaceForward.Application/Services/App/LogService.cs
@@ -12,7 +12,7 @@ namespace InterfaceForward.Application.Services.App
///
[Route("Log")]
[ApiExplorerSettings(GroupName = "应用服务")]
- public class LogService : ApplicationService
+ public class LogService : BaseService
{
private readonly ILogRepository _logRepository;
@@ -97,7 +97,7 @@ namespace InterfaceForward.Application.Services.App
///
///
[HttpGet("GetById")]
- public async Task GetByIdAsync(string id)
+ public async Task GetByIdAsync(string id)
{
return await _logRepository.GetDetailsByIdAsync(id);
}
diff --git a/src/InterfaceForward.Application/Services/BaseService.cs b/src/InterfaceForward.Application/Services/BaseService.cs
new file mode 100644
index 0000000..6385c2f
--- /dev/null
+++ b/src/InterfaceForward.Application/Services/BaseService.cs
@@ -0,0 +1,5 @@
+namespace InterfaceForward.Application.Services;
+
+public abstract class BaseService : ApplicationService
+{
+}
\ No newline at end of file
diff --git a/src/InterfaceForward.Application/Services/Interface/InterfaceReturnConfigService.cs b/src/InterfaceForward.Application/Services/Interface/InterfaceReturnConfigService.cs
index 3ea9901..484511a 100644
--- a/src/InterfaceForward.Application/Services/Interface/InterfaceReturnConfigService.cs
+++ b/src/InterfaceForward.Application/Services/Interface/InterfaceReturnConfigService.cs
@@ -13,7 +13,7 @@ namespace InterfaceForward.Application.Services.Interface;
/// 接口返回配置
///
[ApiExplorerSettings(GroupName = "接口服务")]
-public class InterfaceReturnConfigService : ApplicationService
+public class InterfaceReturnConfigService : BaseService
{
private readonly IInterfaceReturnConfigRepository _interfaceReturnConfigRepository;
private readonly IInterfaceRepository _interfaceRepository;
diff --git a/src/InterfaceForward.Application/Services/Interface/ServiceProviderInterfaceService.cs b/src/InterfaceForward.Application/Services/Interface/ServiceProviderInterfaceService.cs
index d25dde1..337d09c 100644
--- a/src/InterfaceForward.Application/Services/Interface/ServiceProviderInterfaceService.cs
+++ b/src/InterfaceForward.Application/Services/Interface/ServiceProviderInterfaceService.cs
@@ -18,7 +18,7 @@ namespace InterfaceForward.Application.Services.Interface;
/// 服务商接口
///
[ApiExplorerSettings(GroupName = "接口服务")]
-public class ServiceProviderInterfaceService : ApplicationService
+public class ServiceProviderInterfaceService : BaseService
{
private ParameterService ParameterService => LazyServiceProvider.GetRequiredService();
diff --git a/src/InterfaceForward.Application/Services/Interface/SystemInterfaceService.cs b/src/InterfaceForward.Application/Services/Interface/SystemInterfaceService.cs
index ce221c6..8b7aecc 100644
--- a/src/InterfaceForward.Application/Services/Interface/SystemInterfaceService.cs
+++ b/src/InterfaceForward.Application/Services/Interface/SystemInterfaceService.cs
@@ -17,7 +17,7 @@ namespace InterfaceForward.Application.Services.Interface;
/// 系统接口
///
[ApiExplorerSettings(GroupName = "接口服务")]
-public class SystemInterfaceService : ApplicationService
+public class SystemInterfaceService : BaseService
{
#region ctor
diff --git a/src/InterfaceForward.Application/Services/InterfaceForwardService.cs b/src/InterfaceForward.Application/Services/InterfaceForwardService.cs
index b4f35b3..8bd6612 100644
--- a/src/InterfaceForward.Application/Services/InterfaceForwardService.cs
+++ b/src/InterfaceForward.Application/Services/InterfaceForwardService.cs
@@ -1,5 +1,4 @@
using System.ComponentModel.DataAnnotations;
-using Fake.AspNetCore.Mvc.Filters.UnifiedResult;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
@@ -15,12 +14,10 @@ namespace InterfaceForward.Application.Services;
/// 接口转发服务
///
[ApiExplorerSettings(GroupName = "接口转发服务")]
-[TypeFilter(typeof(ForwardAuthorizeFilter))]
-[TypeFilter(typeof(ForwardExceptionFilter))]
-[DisableRequestLog]
+[TypeFilter(typeof(ForwardAuthorizeFilter))]
[AllowAnonymous]
[Route("InterfaceForward")]
-public class InterfaceForwardService : ApplicationService, IInterfaceForwardService
+public class InterfaceForwardService : BaseService, IInterfaceForwardService
{
private readonly InterfaceForwardCommon _forwardCommon;
private readonly ILogRepository _logRepository;
@@ -38,7 +35,6 @@ public class InterfaceForwardService : ApplicationService, IInterfaceForwardServ
_options = options.Value;
}
- [DisableUnifiedResult]
[HttpPost("ForwardWithSubscribe")]
public async Task ForwardWithSubscribeAsync(
[FromQuery] [Required] string upStreamCode,
diff --git a/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapPublishService.cs b/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapPublishService.cs
index 8995185..2f5a027 100644
--- a/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapPublishService.cs
+++ b/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapPublishService.cs
@@ -20,7 +20,7 @@ namespace InterfaceForward.Application.Services.InterfaceMap;
/// 接口映射发布修改
///
[ApiExplorerSettings(GroupName = "接口映射服务")]
-public class InterfaceMapPublishService : ApplicationService
+public class InterfaceMapPublishService : BaseService
{
private readonly static JsonSerializerSettings Settings = new JsonSerializerSettings
{
diff --git a/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapService.cs b/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapService.cs
index f27b53b..45e5553 100644
--- a/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapService.cs
+++ b/src/InterfaceForward.Application/Services/InterfaceMap/InterfaceMapService.cs
@@ -16,7 +16,7 @@ namespace InterfaceForward.Application.Services.InterfaceMap;
/// 接口映射服务
///
[ApiExplorerSettings(GroupName = "接口映射服务")]
-public class InterfaceMapService : ApplicationService
+public class InterfaceMapService : BaseService
{
private readonly IInterfaceMapRepository _interfaceMapRepository;
private readonly IBasicRepository _interfaceRepository;
diff --git a/src/InterfaceForward.Application/Services/Parameter/FixedParameterService.cs b/src/InterfaceForward.Application/Services/Parameter/FixedParameterService.cs
index 6dd062b..3b328f8 100644
--- a/src/InterfaceForward.Application/Services/Parameter/FixedParameterService.cs
+++ b/src/InterfaceForward.Application/Services/Parameter/FixedParameterService.cs
@@ -13,7 +13,7 @@ namespace InterfaceForward.Application.Services.Parameter;
/// 固定参数配置
///
[ApiExplorerSettings(GroupName = "参数服务")]
-public class FixedParameterService : ApplicationService
+public class FixedParameterService : BaseService
{
private readonly IFixedParameterRepository _fixedParameterRepository;
private readonly IServiceProviderRepository _serviceProviderRepository;
diff --git a/src/InterfaceForward.Application/Services/Parameter/FormParameterService.cs b/src/InterfaceForward.Application/Services/Parameter/FormParameterService.cs
index 8d74b59..28f7292 100644
--- a/src/InterfaceForward.Application/Services/Parameter/FormParameterService.cs
+++ b/src/InterfaceForward.Application/Services/Parameter/FormParameterService.cs
@@ -12,7 +12,7 @@ namespace InterfaceForward.Application.Services.Parameter;
/// 表单参数配置
///
[ApiExplorerSettings(GroupName = "参数服务")]
-public class FormParameterService : ApplicationService
+public class FormParameterService : BaseService
{
private readonly IBasicRepository _formParameterRepository;
diff --git a/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs b/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs
index 958dd2c..4916a03 100644
--- a/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs
+++ b/src/InterfaceForward.Application/Services/Parameter/ParameterService.cs
@@ -18,7 +18,7 @@ namespace InterfaceForward.Application.Services.Parameter;
/// 参数服务
///
[ApiExplorerSettings(GroupName = "参数服务")]
-public class ParameterService : ApplicationService
+public class ParameterService : BaseService
{
private readonly IInterfaceRepository _interfaceRepository;
private readonly IParameterRepository _parameterRepository;
diff --git a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAccountService.cs b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAccountService.cs
index a58232c..f2943f9 100644
--- a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAccountService.cs
+++ b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAccountService.cs
@@ -14,7 +14,7 @@ namespace InterfaceForward.Application.Services.ServiceProvider;
/// 服务商账户
///
[ApiExplorerSettings(GroupName = "服务商服务")]
-public class ServiceProviderAccountService : ApplicationService
+public class ServiceProviderAccountService : BaseService
{
private readonly IServiceProviderAccountFieldRepository _serviceProviderAccountFieldRepository;
private readonly IServiceProviderAccountFieldValueRepository _serviceProviderAccountFieldValueRepository;
@@ -211,6 +211,8 @@ public class ServiceProviderAccountService : ApplicationService
var fields =
await _serviceProviderAccountFieldRepository.GetAccountFieldWithValueListByServiceProviderIdAsync(
serviceProviderId);
+
+ var dics = new List>();
foreach (var item in data.Items)
{
// 一行数据
@@ -234,10 +236,11 @@ public class ServiceProviderAccountService : ApplicationService
}
dic[nameof(ServiceProviderAccountPageValueObject.UpdateTime)] = updateTime;
-
- res.Items.Add(dic);
+
+ dics.Add(dic);
}
+ res.Items = dics;
return res;
}
diff --git a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAuthService.cs b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAuthService.cs
index a4529bb..0b2a557 100644
--- a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAuthService.cs
+++ b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderAuthService.cs
@@ -15,7 +15,7 @@ namespace InterfaceForward.Application.Services.ServiceProvider;
/// 服务商授权配置
///
[ApiExplorerSettings(GroupName = "服务商服务")]
-public class ServiceProviderAuthService : ApplicationService
+public class ServiceProviderAuthService : BaseService
{
private readonly IBasicRepository _interfaceRepository;
private readonly IBasicRepository _parameterRepository;
diff --git a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderImportExportService.cs b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderImportExportService.cs
index a487b50..afeaa24 100644
--- a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderImportExportService.cs
+++ b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderImportExportService.cs
@@ -21,7 +21,7 @@ namespace InterfaceForward.Application.Services.ServiceProvider;
/// 导入导出服务
///
[ApiExplorerSettings(GroupName = "服务商服务")]
-public class ServiceProviderImportExportService : ApplicationService
+public class ServiceProviderImportExportService : BaseService
{
private readonly ISugarDbContextProvider _sqlSugarClientProvider;
diff --git a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderService.cs b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderService.cs
index 1c45def..3ffe2a9 100644
--- a/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderService.cs
+++ b/src/InterfaceForward.Application/Services/ServiceProvider/ServiceProviderService.cs
@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations;
using InterfaceForward.Application.Contracts.Dtos.ServiceProvider;
using InterfaceForward.Application.ForwardCore;
-using InterfaceForward.Domain.Shared.Dtos;
using InterfaceForward.Domain.Shared.Enum;
using InterfaceForward.Repositories;
using InterfaceForward.Repositories.Interface.Entitys;
@@ -16,7 +15,7 @@ namespace InterfaceForward.Application.Services.ServiceProvider;
/// 服务商服务
///
[ApiExplorerSettings(GroupName = "服务商服务")]
-public class ServiceProviderService : ApplicationService
+public class ServiceProviderService : BaseService
{
private readonly IBasicRepository _interfaceRepository;
private readonly IServiceProviderRepository _serviceProviderRepository;
diff --git a/src/InterfaceForward.Domain.Shared/Dtos/RequestLogDto.cs b/src/InterfaceForward.Domain.Shared/Dtos/RequestLogDto.cs
index 908d8f2..0018d40 100644
--- a/src/InterfaceForward.Domain.Shared/Dtos/RequestLogDto.cs
+++ b/src/InterfaceForward.Domain.Shared/Dtos/RequestLogDto.cs
@@ -1,19 +1,13 @@
namespace InterfaceForward.Domain.Shared.Dtos;
-public class RequestLogDto
+public class RequestLogDto(Guid requestId)
{
- public const string Init = null;
-
- public RequestLogDto(Guid requestId)
- {
- RequestId = requestId;
- Response = Init;
- }
+ public const string Init = null!;
///
/// 请求Id
///
- public Guid RequestId { get; set; }
+ public Guid RequestId { get; set; } = requestId;
///
/// 请求时间(务必设置)
@@ -33,7 +27,7 @@ public class RequestLogDto
///
/// 发起请求IP
///
- public string ClientIP { get; set; }
+ public string? ClientIp { get; set; }
///
/// 接口代码
@@ -68,7 +62,7 @@ public class RequestLogDto
///
/// 响应结果
///
- public string Response { get; set; }
+ public string Response { get; set; } = Init;
///
/// 是否成功调用
diff --git a/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticeOptions.cs b/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticeOptions.cs
new file mode 100644
index 0000000..a9a8e34
--- /dev/null
+++ b/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticeOptions.cs
@@ -0,0 +1,14 @@
+namespace InterfaceForward.Domain.Shared.FeiShu;
+
+public class FeiShuNoticeOptions
+{
+ ///
+ /// 飞书通知webhook
+ ///
+ public string Webhook { get; set; }
+
+ ///
+ /// 消息标题前缀
+ ///
+ public string TitlePrefix { get; set; }
+}
\ No newline at end of file
diff --git a/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticer.cs b/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticer.cs
new file mode 100644
index 0000000..2d3cbd3
--- /dev/null
+++ b/src/InterfaceForward.Domain.Shared/FeiShu/FeiShuNoticer.cs
@@ -0,0 +1,78 @@
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.Json;
+using Microsoft.Extensions.Logging;
+using Microsoft.Extensions.Options;
+
+namespace InterfaceForward.Domain.Shared.FeiShu;
+
+public class FeiShuNoticer : IFeiShuNoticer
+{
+ private readonly FeiShuNoticeOptions _options;
+ private readonly HttpClient _httpClient;
+ private readonly ILogger _logger;
+
+ public FeiShuNoticer(IOptions options, HttpClient httpClient, ILogger logger)
+ {
+ _options = options.Value;
+ _httpClient = httpClient;
+ _logger = logger;
+ }
+
+ public async Task NoticeAsync(string content, string subTitle = "")
+ {
+ try
+ {
+ if (_options.Webhook.IsNullOrWhiteSpace())
+ {
+ _logger.LogWarning("未配置飞书webhook");
+ return;
+ }
+
+ var title = subTitle.IsNullOrWhiteSpace()
+ ? _options.TitlePrefix
+ : _options.TitlePrefix + "_" + subTitle;
+
+ await HandleNoticeAsync(content, title);
+ }
+ catch (Exception e)
+ {
+ // 这里失败不应该影响业务
+ _logger.LogWarning($"飞书通知失败,{e.Message}");
+ }
+ }
+
+
+ private async Task HandleNoticeAsync(string content, string title)
+ {
+ var message = new
+ {
+ msg_type = "post",
+ content = new
+ {
+ post = new
+ {
+ zh_cn = new
+ {
+ title,
+ content = new List