From 1090907178b156fcc40a0d2e933a619c9333ed98 Mon Sep 17 00:00:00 2001 From: chenchun Date: Fri, 29 Nov 2024 18:01:54 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=8A=A8=E6=80=81api?= =?UTF-8?q?=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SwaggerAddExtensions.cs | 131 +++++++++--------- .../Services/AccountService.cs | 4 +- .../Dtos/UserRoleMenuDto.cs | 4 +- .../Managers/AccountManager.cs | 4 +- Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs | 47 ++++--- 5 files changed, 99 insertions(+), 91 deletions(-) diff --git a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs index 0476e169..7f446586 100644 --- a/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs +++ b/Yi.Abp.Net8/framework/Yi.Framework.AspNetCore/Microsoft/Extensions/DependencyInjection/SwaggerAddExtensions.cs @@ -9,84 +9,89 @@ using Microsoft.OpenApi.Any; using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Options; namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection { public static class SwaggerAddExtensions { - public static IServiceCollection AddYiSwaggerGen(this IServiceCollection services, Action? action=null) + public static IServiceCollection AddYiSwaggerGen(this IServiceCollection services, + Action? action = null) { - - var serviceProvider = services.BuildServiceProvider(); - var mvcOptions = serviceProvider.GetRequiredService>(); - - var mvcSettings = mvcOptions.Value.ConventionalControllers.ConventionalControllerSettings.DistinctBy(x => x.RemoteServiceName); + var mvcOptions = services.GetPreConfigureActions().Configure(); + + var mvcSettings = + mvcOptions.ConventionalControllers.ConventionalControllerSettings.DistinctBy(x => x.RemoteServiceName); services.AddAbpSwaggerGen( - options => - { - if (action is not null) + options => { - action.Invoke(options); - } - - // 配置分组,还需要去重,支持重写,如果外部传入后,将以外部为准 - foreach (var setting in mvcSettings.OrderBy(x => x.RemoteServiceName)) - { - if (!options.SwaggerGeneratorOptions.SwaggerDocs.ContainsKey(setting.RemoteServiceName)) + if (action is not null) { - options.SwaggerDoc(setting.RemoteServiceName, new OpenApiInfo { Title = setting.RemoteServiceName, Version = "v1" }); + action.Invoke(options); } - } - // 根据分组名称过滤 API 文档 - options.DocInclusionPredicate((docName, apiDesc) => - { - if (apiDesc.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor) + // 配置分组,还需要去重,支持重写,如果外部传入后,将以外部为准 + foreach (var setting in mvcSettings.OrderBy(x => x.RemoteServiceName)) { - var settingOrNull = mvcSettings.Where(x => x.Assembly == controllerActionDescriptor.ControllerTypeInfo.Assembly).FirstOrDefault(); - if (settingOrNull is not null) + if (!options.SwaggerGeneratorOptions.SwaggerDocs.ContainsKey(setting.RemoteServiceName)) { - return docName == settingOrNull.RemoteServiceName; + options.SwaggerDoc(setting.RemoteServiceName, + new OpenApiInfo { Title = setting.RemoteServiceName, Version = "v1" }); } } - return false; - }); - options.CustomSchemaIds(type => type.FullName); - var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); - if (basePath is not null) - { - foreach (var item in Directory.GetFiles(basePath, "*.xml")) + // 根据分组名称过滤 API 文档 + options.DocInclusionPredicate((docName, apiDesc) => { - options.IncludeXmlComments(item, true); + if (apiDesc.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor) + { + var settingOrNull = mvcSettings + .Where(x => x.Assembly == controllerActionDescriptor.ControllerTypeInfo.Assembly) + .FirstOrDefault(); + if (settingOrNull is not null) + { + return docName == settingOrNull.RemoteServiceName; + } + } + + return false; + }); + + options.CustomSchemaIds(type => type.FullName); + var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location); + if (basePath is not null) + { + foreach (var item in Directory.GetFiles(basePath, "*.xml")) + { + options.IncludeXmlComments(item, true); + } } + + options.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme() + { + Description = "直接输入Token即可", + Name = "Authorization", + In = ParameterLocation.Header, + Type = SecuritySchemeType.Http, + Scheme = "bearer" + }); + var scheme = new OpenApiSecurityScheme() + { + Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" } + }; + options.AddSecurityRequirement(new OpenApiSecurityRequirement() + { + [scheme] = new string[0] + }); + + options.OperationFilter(); + options.SchemaFilter(); } + ); - options.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme() - { - Description = "直接输入Token即可", - Name = "Authorization", - In = ParameterLocation.Header, - Type = SecuritySchemeType.Http, - Scheme = "bearer" - }); - var scheme = new OpenApiSecurityScheme() - { - Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" } - }; - options.AddSecurityRequirement(new OpenApiSecurityRequirement() - { - [scheme] = new string[0] - }); - - options.OperationFilter(); - options.SchemaFilter(); - } - ); - - return services; } @@ -103,7 +108,6 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection /// /// /// - public void Apply(OpenApiSchema model, SchemaFilterContext context) { if (context.Type.IsEnum) @@ -112,7 +116,7 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection model.Type = "string"; model.Format = null; - + StringBuilder stringBuilder = new StringBuilder(); Enum.GetNames(context.Type) .ToList() @@ -121,9 +125,10 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection Enum e = (Enum)Enum.Parse(context.Type, name); var descrptionOrNull = GetEnumDescription(e); model.Enum.Add(new OpenApiString(name)); - stringBuilder.Append($"【枚举:{name}{(descrptionOrNull is null ? string.Empty : $"({descrptionOrNull})")}={Convert.ToInt64(Enum.Parse(context.Type, name))}】
"); + stringBuilder.Append( + $"【枚举:{name}{(descrptionOrNull is null ? string.Empty : $"({descrptionOrNull})")}={Convert.ToInt64(Enum.Parse(context.Type, name))}】
"); }); - model.Description= stringBuilder.ToString(); + model.Description = stringBuilder.ToString(); } } @@ -133,13 +138,13 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length > 0 ? attributes[0].Description : null; } - } public class AddRequiredHeaderParameter : IOperationFilter { public static string HeaderKey { get; set; } = "__tenant"; + public void Apply(OpenApiOperation operation, OperationFilterContext context) { if (operation.Parameters == null) @@ -150,8 +155,8 @@ namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection In = ParameterLocation.Header, Required = false, AllowEmptyValue = true, - Description="租户id或者租户名称(可空为默认租户)" + Description = "租户id或者租户名称(可空为默认租户)" }); } } -} +} \ No newline at end of file diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs index 388cf078..4fb3b4a3 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Application/Services/AccountService.cs @@ -355,13 +355,13 @@ namespace Yi.Framework.Rbac.Application.Services { //将后端菜单转换成前端路由,组件级别需要过滤 output = - ObjectMapper.Map, List>(menus).Vue3RuoYiRouterBuild(); + ObjectMapper.Map, List>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Ruoyi).ToList()).Vue3RuoYiRouterBuild(); } else if (routerType == "pure") { //将后端菜单转换成前端路由,组件级别需要过滤 output = - ObjectMapper.Map, List>(menus).Vue3PureRouterBuild(); + ObjectMapper.Map, List>(menus.Where(x=>x.MenuSource==MenuSourceEnum.Pure).ToList()).Vue3PureRouterBuild(); } return output; diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/UserRoleMenuDto.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/UserRoleMenuDto.cs index 199b98e9..e647bab5 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/UserRoleMenuDto.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain.Shared/Dtos/UserRoleMenuDto.cs @@ -9,8 +9,8 @@ namespace Yi.Framework.Rbac.Domain.Shared.Dtos public HashSet Roles { get; set; } = new(); public HashSet Menus { get; set; } = new(); - public List RoleCodes { get; set; } = new(); - public List PermissionCodes { get; set; } = new(); + public HashSet RoleCodes { get; set; } = new(); + public HashSet PermissionCodes { get; set; } = new(); } public class UserDto diff --git a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs index 7051f71c..746222f0 100644 --- a/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs +++ b/Yi.Abp.Net8/module/rbac/Yi.Framework.Rbac.Domain/Managers/AccountManager.cs @@ -217,8 +217,8 @@ namespace Yi.Framework.Rbac.Domain.Managers } else { - dto.PermissionCodes?.ForEach(per => AddToClaim(claims, TokenTypeConst.Permission, per)); - dto.RoleCodes?.ForEach(role => AddToClaim(claims, AbpClaimTypes.Role, role)); + dto.PermissionCodes?.ToList()?.ForEach(per => AddToClaim(claims, TokenTypeConst.Permission, per)); + dto.RoleCodes?.ToList()?.ForEach(role => AddToClaim(claims, AbpClaimTypes.Role, role)); } return claims; diff --git a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs index 50211fa2..bcf35ec9 100644 --- a/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs +++ b/Yi.Abp.Net8/src/Yi.Abp.Web/YiAbpWebModule.cs @@ -66,6 +66,30 @@ namespace Yi.Abp.Web { private const string DefaultCorsPolicyName = "Default"; + public override void PreConfigureServices(ServiceConfigurationContext context) + { + //动态Api-改进在pre中配置,启动更快 + PreConfigure(options => + { + options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, + options => options.RemoteServiceName = "default"); + options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, + options => options.RemoteServiceName = "rbac"); + options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, + options => options.RemoteServiceName = "bbs"); + options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly, + options => options.RemoteServiceName = "chat-hub"); + options.ConventionalControllers.Create( + typeof(YiFrameworkTenantManagementApplicationModule).Assembly, + options => options.RemoteServiceName = "tenant-management"); + options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly, + options => options.RemoteServiceName = "code-gen"); + + //统一前缀 + options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app"); + }); + } + public override Task ConfigureServicesAsync(ServiceConfigurationContext context) { var configuration = context.Services.GetConfiguration(); @@ -91,28 +115,7 @@ namespace Yi.Abp.Web //配置错误处理显示详情 Configure(options => { options.SendExceptionsDetailsToClients = true; }); - - //动态Api - Configure(options => - { - options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, - options => options.RemoteServiceName = "default"); - options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, - options => options.RemoteServiceName = "rbac"); - options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, - options => options.RemoteServiceName = "bbs"); - options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly, - options => options.RemoteServiceName = "chat-hub"); - options.ConventionalControllers.Create( - typeof(YiFrameworkTenantManagementApplicationModule).Assembly, - options => options.RemoteServiceName = "tenant-management"); - options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly, - options => options.RemoteServiceName = "code-gen"); - - //统一前缀 - options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app"); - }); - + //【NewtonsoftJson严重问题!!!!!逆天】设置api格式,留给后人铭记 // service.AddControllers().AddNewtonsoftJson(options => // {