diff --git a/aspnet-core/LINGYUN.MicroService.SingleProject.sln b/aspnet-core/LINGYUN.MicroService.SingleProject.sln index 34467c4f9..24066a7de 100644 --- a/aspnet-core/LINGYUN.MicroService.SingleProject.sln +++ b/aspnet-core/LINGYUN.MicroService.SingleProject.sln @@ -494,7 +494,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Mvc. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.AspNetCore.Wrapper", "framework\common\LINGYUN.Abp.AspNetCore.Wrapper\LINGYUN.Abp.AspNetCore.Wrapper.csproj", "{FDBA1B4A-CC5D-4710-AB8C-FA5A91B91BDE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.OpenIddict.AspNetCore", "modules\openIddict\LINGYUN.Abp.OpenIddict.AspNetCore\LINGYUN.Abp.OpenIddict.AspNetCore.csproj", "{6026DAE3-F2AD-4F6B-99EF-EEAAA5873861}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.OpenIddict.AspNetCore", "modules\openIddict\LINGYUN.Abp.OpenIddict.AspNetCore\LINGYUN.Abp.OpenIddict.AspNetCore.csproj", "{6026DAE3-F2AD-4F6B-99EF-EEAAA5873861}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs index 7181af47a..840736a10 100644 --- a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs +++ b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/AbpAspNetCoreMvcWrapperModule.cs @@ -5,7 +5,9 @@ using LINGYUN.Abp.Wrapper; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; +using System.Collections.Generic; using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.ApiExploring; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.AspNetCore.Mvc.ProxyScripting; using Volo.Abp.Content; diff --git a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ApiExploring/AbpWrapResultApiDescriptionProvider.cs b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ApiExploring/AbpWrapResultApiDescriptionProvider.cs new file mode 100644 index 000000000..25b88ff96 --- /dev/null +++ b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/ApiExploring/AbpWrapResultApiDescriptionProvider.cs @@ -0,0 +1,153 @@ +using LINGYUN.Abp.Wrapper; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.ApiExplorer; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using Volo.Abp.AspNetCore.Mvc; +using Volo.Abp.AspNetCore.Mvc.ApiExploring; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Reflection; +using Volo.Abp.Threading; + +namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper.ApiExploring; +public class AbpWrapResultApiDescriptionProvider : IApiDescriptionProvider, ITransientDependency +{ + private readonly MvcOptions _mvcOptions; + private readonly AbpWrapperOptions _wrapperOptions; + private readonly AbpRemoteServiceApiDescriptionProviderOptions _providerOptions; + private readonly IWrapResultChecker _wrapResultChecker; + private readonly IModelMetadataProvider _modelMetadataProvider; + + public AbpWrapResultApiDescriptionProvider( + IOptions mvcOptions, + IOptions wrapperOptions, + IOptions providerOptions, + IWrapResultChecker wrapResultChecker, + IModelMetadataProvider modelMetadataProvider) + { + _mvcOptions = mvcOptions.Value; + _wrapperOptions = wrapperOptions.Value; + _providerOptions = providerOptions.Value; + _wrapResultChecker = wrapResultChecker; + _modelMetadataProvider = modelMetadataProvider; + } + + public int Order => -999; + + public virtual void OnProvidersExecuted(ApiDescriptionProviderContext context) + { + } + + public virtual void OnProvidersExecuting(ApiDescriptionProviderContext context) + { + WrapperOKResponse(context); + } + + protected virtual void WrapperOKResponse(ApiDescriptionProviderContext context) + { + foreach (var result in context.Results.Where(x => x.IsRemoteService())) + { + var actionProducesResponseTypeAttributes = + ReflectionHelper.GetAttributesOfMemberOrDeclaringType( + result.ActionDescriptor.GetMethodInfo()); + if (actionProducesResponseTypeAttributes.Any(x => x.StatusCode == (int)_wrapperOptions.HttpStatusCode)) + { + continue; + } + + if (_wrapResultChecker.WrapOnAction(result.ActionDescriptor) && + result.ActionDescriptor is ControllerActionDescriptor actionDescriptor) + { + var returnType = AsyncHelper.UnwrapTask(actionDescriptor.MethodInfo.ReturnType); + + Type wrapResultType = null; + if (returnType == null || returnType == typeof(void)) + { + wrapResultType = typeof(WrapResult); + } + else + { + wrapResultType = typeof(WrapResult<>).MakeGenericType(returnType); + } + + var responseType = new ApiResponseType + { + Type = wrapResultType, + StatusCode = (int)_wrapperOptions.HttpStatusCode, + ModelMetadata = _modelMetadataProvider.GetMetadataForType(wrapResultType) + }; + + foreach (var responseTypeMetadataProvider in _mvcOptions.OutputFormatters.OfType()) + { + var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null, wrapResultType); + if (formatterSupportedContentTypes == null) + { + continue; + } + + foreach (var formatterSupportedContentType in formatterSupportedContentTypes) + { + responseType.ApiResponseFormats.Add(new ApiResponseFormat + { + Formatter = (IOutputFormatter)responseTypeMetadataProvider, + MediaType = formatterSupportedContentType + }); + } + } + // TODO: 是否有必要对其他响应代码定义包装结果? + // 例外1: 当用户传递 _AbpDontWrapResult 请求头时, 响应结果与预期不一致 + // 例外2: 当控制器Url在被忽略Url中, 响应结果与预期不一致 + // 例外3: 当引发异常在被忽略异常中, 响应结果为 RemoteServiceErrorResponse 对象, 与预期不一致 + + result.SupportedResponseTypes.RemoveAll(x => x.StatusCode == responseType.StatusCode); + result.SupportedResponseTypes.AddIfNotContains( + x => x.StatusCode == responseType.StatusCode, + () => responseType); + WrapperErrorResponse(result); + } + } + } + + protected virtual void WrapperErrorResponse(ApiDescription description) + { + foreach (var apiResponse in _providerOptions.SupportedResponseTypes) + { + var wrapResultType = typeof(WrapResult); + var responseType = new ApiResponseType + { + Type = wrapResultType, + StatusCode = apiResponse.StatusCode, + ModelMetadata = _modelMetadataProvider.GetMetadataForType(wrapResultType) + }; + + foreach (var responseTypeMetadataProvider in _mvcOptions.OutputFormatters.OfType()) + { + var formatterSupportedContentTypes = responseTypeMetadataProvider.GetSupportedContentTypes(null, responseType.Type); + if (formatterSupportedContentTypes == null) + { + continue; + } + + foreach (var formatterSupportedContentType in formatterSupportedContentTypes) + { + responseType.ApiResponseFormats.Add(new ApiResponseFormat + { + Formatter = (IOutputFormatter)responseTypeMetadataProvider, + MediaType = formatterSupportedContentType + }); + } + } + + description.SupportedResponseTypes.RemoveAll(x => x.StatusCode == responseType.StatusCode); + description.SupportedResponseTypes.AddIfNotContains( + x => x.StatusCode == responseType.StatusCode, + () => responseType); + } + } +} diff --git a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs index 9e87aaf18..2ec59073a 100644 --- a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs +++ b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/IWrapResultChecker.cs @@ -1,9 +1,12 @@ -using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.Abstractions; +using Microsoft.AspNetCore.Mvc.Filters; namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper { public interface IWrapResultChecker { + bool WrapOnAction(ActionDescriptor actionDescriptor); + bool WrapOnExecution(FilterContext context); bool WrapOnException(ExceptionContext context); diff --git a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs index 0f4615848..8ebaf38a3 100644 --- a/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs +++ b/aspnet-core/framework/mvc/LINGYUN.Abp.AspNetCore.Mvc.Wrapper/LINGYUN/Abp/AspNetCore/Mvc/Wrapper/WrapResultChecker.cs @@ -20,6 +20,16 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper Options = optionsMonitor.CurrentValue; } + public virtual bool WrapOnAction(ActionDescriptor actionDescriptor) + { + if (!Options.IsEnabled) + { + return false; + } + + return CheckForActionDescriptor(actionDescriptor); + } + public bool WrapOnException(ExceptionContext context) { if (!CheckForBase(context)) @@ -32,6 +42,11 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper public bool WrapOnException(PageHandlerExecutedContext context) { + if (!CheckForBase(context)) + { + return false; + } + return CheckForException(context.Exception); } @@ -40,7 +55,6 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper return CheckForBase(context); } - protected virtual bool CheckForBase(FilterContext context) { if (!Options.IsEnabled) @@ -48,49 +62,56 @@ namespace LINGYUN.Abp.AspNetCore.Mvc.Wrapper return false; } + // 用户传递不包装 if (context.HttpContext.Request.Headers.ContainsKey(AbpHttpWrapConsts.AbpDontWrapResult)) { return false; } - if (context.ActionDescriptor is ControllerActionDescriptor descriptor) + // 用户传递需要包装 + if (context.HttpContext.Request.Headers.ContainsKey(AbpHttpWrapConsts.AbpWrapResult)) { - if (!context.ActionDescriptor.HasObjectResult()) - { - return false; - } + return true; + } - //if (!context.HttpContext.Request.CanAccept(MimeTypes.Application.Json)) - //{ - // return false; - //} + if (!CheckForUrl(context)) + { + return false; + } + + return CheckForActionDescriptor(context.ActionDescriptor); + } - if (!CheckForUrl(context)) + protected virtual bool CheckForActionDescriptor(ActionDescriptor descriptor) + { + if (descriptor is ControllerActionDescriptor controllerActionDescriptor) + { + if (!descriptor.HasObjectResult()) { return false; } - if (!CheckForNamespace(descriptor)) + if (!CheckForNamespace(controllerActionDescriptor)) { return false; } - if (!CheckForController(descriptor)) + if (!CheckForController(controllerActionDescriptor)) { return false; } - if (!CheckForInterfaces(descriptor)) + if (!CheckForInterfaces(controllerActionDescriptor)) { return false; } - if (!CheckForMethod(descriptor)) + if (!CheckForMethod(controllerActionDescriptor)) { return false; } - if (!CheckForReturnType(descriptor)) + if (!CheckForReturnType(controllerActionDescriptor)) { return false; } diff --git a/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/AbpSettingManagementApplicationContractsModule.cs b/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/AbpSettingManagementApplicationContractsModule.cs index 3284bc341..a239c8666 100644 --- a/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/AbpSettingManagementApplicationContractsModule.cs +++ b/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/AbpSettingManagementApplicationContractsModule.cs @@ -1,4 +1,7 @@ -using Volo.Abp.Application; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using Volo.Abp.Application; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.SettingManagement; @@ -11,6 +14,11 @@ namespace LINGYUN.Abp.SettingManagement [DependsOn(typeof(AbpSettingManagementDomainSharedModule))] public class AbpSettingManagementApplicationContractsModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + AutoAddSettingProviders(context.Services); + } + public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => @@ -25,5 +33,31 @@ namespace LINGYUN.Abp.SettingManagement .AddVirtualJson("/LINGYUN/Abp/SettingManagement/Localization/ApplicationContracts"); }); } + + private static void AutoAddSettingProviders(IServiceCollection services) + { + var userSettingProviders = new List(); + var globalSettingProviders = new List(); + + services.OnRegistered(context => + { + if (typeof(IUserSettingAppService).IsAssignableFrom(context.ImplementationType) && + context.ImplementationType.Name.EndsWith("AppService")) + { + userSettingProviders.Add(context.ImplementationType); + } + if (typeof(IReadonlySettingAppService).IsAssignableFrom(context.ImplementationType) && + context.ImplementationType.Name.EndsWith("AppService")) + { + globalSettingProviders.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.UserSettingProviders.AddIfNotContains(userSettingProviders); + options.GlobalSettingProviders.AddIfNotContains(globalSettingProviders); + }); + } } } diff --git a/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/SettingManagementMergeOptions.cs b/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/SettingManagementMergeOptions.cs new file mode 100644 index 000000000..adeee18ba --- /dev/null +++ b/aspnet-core/framework/settings/LINGYUN.Abp.SettingManagement.Application.Contracts/LINGYUN/Abp/SettingManagement/SettingManagementMergeOptions.cs @@ -0,0 +1,13 @@ +using Volo.Abp.Collections; + +namespace LINGYUN.Abp.SettingManagement; +public class SettingManagementMergeOptions +{ + public ITypeList UserSettingProviders { get; } + public ITypeList GlobalSettingProviders { get; } + public SettingManagementMergeOptions() + { + UserSettingProviders = new TypeList(); + GlobalSettingProviders = new TypeList(); + } +} diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/SettingMergeController.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/SettingMergeController.cs new file mode 100644 index 000000000..8138e9bfa --- /dev/null +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/SettingMergeController.cs @@ -0,0 +1,70 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace LY.MicroService.Applications.Single.Controllers; + +[ExposeServices( + typeof(SettingController), + typeof(SettingMergeController))] +public class SettingMergeController : SettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public SettingMergeController( + ISettingAppService settingAppService, + ISettingTestAppService settingTestAppService, + IOptions mergeOptions) + : base(settingAppService, settingTestAppService) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-tenant")] + public async override Task GetAllForCurrentTenantAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentTenantAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } + + [HttpGet] + [Route("by-global")] + public async override Task GetAllForGlobalAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForGlobalAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/UserSettingMergeController.cs b/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/UserSettingMergeController.cs new file mode 100644 index 000000000..ae0580f07 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.Applications.Single/Controllers/UserSettingMergeController.cs @@ -0,0 +1,45 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace LY.MicroService.Applications.Single.Controllers; + +[ExposeServices( + typeof(UserSettingController), + typeof(UserSettingMergeController))] +public class UserSettingMergeController : UserSettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public UserSettingMergeController( + IUserSettingAppService service, + IOptions mergeOptions) + : base(service) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-user")] + public async override Task GetAllForCurrentUserAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(UserSettingMergeController), + }; + foreach (var serviceType in _mergeOptions.UserSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentUserAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs index 289713f67..71779aad2 100644 --- a/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.Applications.Single/MicroServiceApplicationsSingleModule.Configure.cs @@ -722,7 +722,7 @@ public partial class MicroServiceApplicationsSingleModule } }; }); - services.AddAlwaysAllowAuthorization(); + if (isDevelopment) { services.AddAlwaysAllowAuthorization(); diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/SettingMergeController.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/SettingMergeController.cs new file mode 100644 index 000000000..3c8cf4268 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/SettingMergeController.cs @@ -0,0 +1,74 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LY.MicroService.BackendAdmin.Controllers; + +[ExposeServices( + typeof(SettingController), + typeof(SettingMergeController))] +public class SettingMergeController : SettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public SettingMergeController( + ISettingAppService settingAppService, + ISettingTestAppService settingTestAppService, + IOptions mergeOptions) + : base(settingAppService, settingTestAppService) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-tenant")] + public async override Task GetAllForCurrentTenantAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentTenantAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } + + [HttpGet] + [Route("by-global")] + public async override Task GetAllForGlobalAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(SettingMergeController), + }; + foreach (var serviceType in _mergeOptions.GlobalSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForGlobalAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +} diff --git a/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/UserSettingMergeController.cs b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/UserSettingMergeController.cs new file mode 100644 index 000000000..9b42946c3 --- /dev/null +++ b/aspnet-core/services/LY.MicroService.BackendAdmin.HttpApi.Host/Controllers/UserSettingMergeController.cs @@ -0,0 +1,49 @@ +using LINGYUN.Abp.SettingManagement; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LY.MicroService.BackendAdmin.Controllers; + +[ExposeServices( + typeof(UserSettingController), + typeof(UserSettingMergeController))] +public class UserSettingMergeController : UserSettingController +{ + private readonly SettingManagementMergeOptions _mergeOptions; + public UserSettingMergeController( + IUserSettingAppService service, + IOptions mergeOptions) + : base(service) + { + _mergeOptions = mergeOptions.Value; + } + + [HttpGet] + [Route("by-current-user")] + public async override Task GetAllForCurrentUserAsync() + { + var result = new SettingGroupResult(); + var markTypeMap = new List + { + typeof(UserSettingMergeController), + }; + foreach (var serviceType in _mergeOptions.UserSettingProviders + .Where(type => !markTypeMap.Any(markType => type.IsAssignableFrom(markType)))) + { + var settingService = LazyServiceProvider.LazyGetRequiredService(serviceType).As(); + var currentResult = await settingService.GetAllForCurrentUserAsync(); + foreach (var group in currentResult.Items) + { + result.AddGroup(group); + } + markTypeMap.Add(serviceType); + } + + return result; + } +}