This commit is contained in:
南浔
2025-07-31 22:52:41 +08:00
73 changed files with 7108 additions and 16 deletions
@@ -15,6 +15,14 @@ namespace Apimanager_backend.Config
CreateMap<CreateApiInfo, Api>();
CreateMap<Apipackage, PackageInfoDto>();
CreateMap<AddPackageDto, Apipackage>();
CreateMap<OrderDto, Order>();
CreateMap<PaymentConfig, PaymentConfigDto>();
CreateMap<EpayResponse, PayReturnData>()
.ForMember(dest => dest.Success, opt => opt.MapFrom(src => src.code == 1))
.ForMember(dest => dest.QrCode, opt => opt.MapFrom(src => src.qrcode))
.ForMember(dest => dest.OrderNum, opt => opt.MapFrom(src => src.trade_no))
.ForMember(dest => dest.PayUrl, opt => opt.MapFrom(src => src.payurl))
.ForMember(dest => dest.Urlscheme, opt => opt.MapFrom(src => src.urlscheme));
}
}
}
@@ -1,12 +1,15 @@
using Apimanager_backend.Dtos;
using Apimanager_backend.Services;
using Apimanager_backend.Tools;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using Public;
using StackExchange.Redis;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Reflection;
using System.Text;
using System.Threading.RateLimiting;
namespace Apimanager_backend.Config
{
@@ -22,10 +25,17 @@ namespace Apimanager_backend.Config
services.AddScoped<IAdminService, AdminService>();
services.AddScoped<IApiService, ApiService>();
services.AddScoped<IPackageService, PackageService>();
services.AddScoped<IOrderService, OrderService>();
services.AddScoped<IApiPackageItemService, ApiPackageItemService>();
services.AddScoped<IUserPackageService, UserPackageService>();
services.AddScoped<ISystemConfigService, SystemConfigService>();
services.AddScoped<IPaymentConfigService, PaymentConfigService>();
services.AddScoped<IPayService, PayService>();
services.AddSingleton<ITokenService, TokenService>();
services.AddSingleton<IRefreshTokenService, RefreshTokenService>();
services.AddSingleton<IEmailService, EmailService>();
services.AddApiHandler(configuration);
services.AddRateLimit(configuration);
return services;
}
public static IServiceCollection AddJWTService(this IServiceCollection services,IConfiguration configuration)
@@ -100,5 +110,76 @@ namespace Apimanager_backend.Config
});
return services;
}
public static IServiceCollection AddApiHandler(this IServiceCollection services,IConfiguration configuration1)
{
/*
var handlerTypes = Assembly.GetExecutingAssembly()
.GetTypes()
.Where(t => typeof(IBillableApiHandler).IsAssignableFrom(t) && !t.IsInterface && !t.IsAbstract);
foreach(var type in handlerTypes)
{
services.AddTransient(type);
}
*/
services.AddSingleton<PluginLoaderService>();
var pluginLoaderService = services.BuildServiceProvider()
.GetRequiredService<PluginLoaderService>();
pluginLoaderService.LoadPlugins(services);
services.AddScoped<BillableApiDispatcher>();
return services;
}
public static IServiceCollection AddRateLimit(this IServiceCollection service, IConfiguration configuration1)
{
service.AddRateLimiter(option =>
{
option.RejectionStatusCode = 429;
option.OnRejected = async (context, ct) =>
{
context.HttpContext.Response.ContentType = "application/json";
await context.HttpContext.Response.WriteAsJsonAsync(new ResponseBase<object?>()
{
Code = 3003,
Data = null,
Message = "API调用已达上限!"
}, ct);
};
option.AddPolicy("DynamicPerUser", context =>
{
// 从前面中间件塞进来的 user 对象
var dto = context.Items["rateLimit"] as RateLimiterDto;
string partitionKey;
int limit;
if (dto is null)
{
return RateLimitPartition.GetConcurrencyLimiter("unauthorized", _ => new ConcurrencyLimiterOptions
{
PermitLimit = 0, // 不允许任何请求
QueueProcessingOrder = QueueProcessingOrder.OldestFirst,
QueueLimit = 0
});
}
else
{
partitionKey = dto.UserId.ToString();
limit = dto.RateLimit;
}
return RateLimitPartition.GetFixedWindowLimiter(
partitionKey,
_ => new FixedWindowRateLimiterOptions
{
PermitLimit = limit,
Window = TimeSpan.FromMinutes(1),
QueueLimit = 0,
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
});
});
});
return service;
}
}
}