From 01bcad6993522e613c7ca18ee6d03291f28d65c9 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Thu, 29 Dec 2022 11:26:27 +0800 Subject: [PATCH] add abp script to elsa --- .../LINGYUN/Abp/Elsa/AbpElsaModule.cs | 39 ++-- .../JavaScript/ConfigureJavaScriptEngine.cs | 177 ++++++++++++++++++ .../Scripting/Liquid/ConfigureLiquidEngine.cs | 63 +++++++ .../Scripting/Liquid/LiquidAbpAccessor.cs | 5 + ...owManagementHttpApiHostModule.Configure.cs | 17 +- 5 files changed, 274 insertions(+), 27 deletions(-) create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/JavaScript/ConfigureJavaScriptEngine.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/ConfigureLiquidEngine.cs create mode 100644 aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/LiquidAbpAccessor.cs diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/AbpElsaModule.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/AbpElsaModule.cs index 31075b2dc..2ddeadf17 100644 --- a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/AbpElsaModule.cs +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/AbpElsaModule.cs @@ -1,6 +1,7 @@ using Elsa; using Elsa.Services; using LINGYUN.Abp.Elsa.Localization; +using LINGYUN.Abp.Elsa.Scripting.JavaScript; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Newtonsoft.Json; @@ -26,28 +27,28 @@ public class AbpElsaModule : AbpModule { var builder = context.Services.GetPreConfigureActions(); - context.Services.AddElsa(options => - { - options.AddCustomTenantAccessor(); - options.AddConsoleActivities(); - options.AddJavaScriptActivities(); - options.UseJsonSerializer((provider) => + context.Services + .AddElsa(options => { - var jsonOptions = provider.GetRequiredService>(); - var jsonConverters = jsonOptions.Value.Converters - .Select(c => (JsonConverter)provider.GetRequiredService(c)) - .ToList(); - var jsonSettings = new JsonSerializerSettings(); - jsonSettings.Converters.InsertRange(0, jsonConverters); - - return JsonSerializer.Create(jsonSettings); - }); + options.AddCustomTenantAccessor(); + options.AddConsoleActivities(); + options.AddJavaScriptActivities(); + options.UseJsonSerializer((provider) => + { + var jsonOptions = provider.GetRequiredService>(); + var jsonConverters = jsonOptions.Value.Converters + .Select(c => (JsonConverter)provider.GetRequiredService(c)) + .ToList(); + var jsonSettings = new JsonSerializerSettings(); + jsonSettings.Converters.InsertRange(0, jsonConverters); - builder.Configure(options); - }); + return JsonSerializer.Create(jsonSettings); + }); - context.Services.Replace(ServiceLifetime.Singleton); - context.Services.Replace(ServiceLifetime.Scoped); + builder.Configure(options); + }) + .AddNotificationHandlers(typeof(ConfigureJavaScriptEngine)) + .Replace(ServiceLifetime.Singleton); Configure(options => { diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/JavaScript/ConfigureJavaScriptEngine.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/JavaScript/ConfigureJavaScriptEngine.cs new file mode 100644 index 000000000..96b2dc082 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/JavaScript/ConfigureJavaScriptEngine.cs @@ -0,0 +1,177 @@ +using Elsa.Scripting.JavaScript.Events; +using Elsa.Scripting.JavaScript.Messages; +using MediatR; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Guids; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Settings; +using Volo.Abp.Timing; + +namespace LINGYUN.Abp.Elsa.Scripting.JavaScript; + +public class ConfigureJavaScriptEngine : INotificationHandler, INotificationHandler +{ + private readonly IClock _clock; + private readonly ICurrentTenant _currentTenant; + private readonly AbpLocalizationOptions _localizationOptions; + private readonly IStringLocalizerFactory _localizerFactory; + private readonly IGuidGenerator _guidGenerator; + private readonly ISettingProvider _settingProvider; + private readonly IPermissionChecker _permissionChecker; + + public ConfigureJavaScriptEngine( + IClock clock, + ICurrentTenant currentTenant, + IOptions localizationOptions, + IStringLocalizerFactory localizerFactory, + IGuidGenerator guidGenerator, + ISettingProvider settingProvider, + IPermissionChecker permissionChecker) + { + _clock = clock; + _currentTenant = currentTenant; + _localizationOptions = localizationOptions.Value; + _localizerFactory = localizerFactory; + _guidGenerator = guidGenerator; + _settingProvider = settingProvider; + _permissionChecker = permissionChecker; + } + + public Task Handle(RenderingTypeScriptDefinitions notification, CancellationToken cancellationToken) + { + var output = notification.Output; + + output.AppendLine("declare interface Clock {"); + output.AppendLine(" now(): DateTime;"); + output.AppendLine(" normalize(dateTime: DateTime): DateTime;"); + output.AppendLine("}"); + + output.AppendLine("declare interface CurrentTenant {"); + output.AppendLine(" id(): string;"); + output.AppendLine(" name(): string;"); + output.AppendLine("}"); + + output.AppendLine("declare interface Utils {"); + output.AppendLine(" guid(): string;"); + output.AppendLine("}"); + + output.AppendLine("declare interface Localization {"); + output.AppendLine(" localize(key: string, resourceName?: string): string;"); + output.AppendLine("}"); + + output.AppendLine("declare interface Setting {"); + output.AppendLine(" get(name: string): any;"); + output.AppendLine(" getNumber(name: string): number;"); + output.AppendLine(" getBoolean(name: string): boolean;"); + output.AppendLine("}"); + + output.AppendLine("declare interface Auth {"); + output.AppendLine(" isGranted(name: string): boolean;"); + output.AppendLine(" isAnyGranted(names: string[]): boolean;"); + output.AppendLine(" areAllGranted(names: string[]): boolean;"); + output.AppendLine("}"); + + output.AppendLine("declare interface Abp {"); + output.AppendLine(" clock: Clock;"); + output.AppendLine(" currentTenant: CurrentTenant;"); + output.AppendLine(" utils: Utils;"); + output.AppendLine(" localization: Localization;"); + output.AppendLine(" setting: Setting;"); + output.AppendLine(" auth: Auth;"); + output.AppendLine("}"); + + output.AppendLine("declare const abp: Abp;"); + + return Task.CompletedTask; + } + + public Task Handle(EvaluatingJavaScriptExpression notification, CancellationToken cancellationToken) + { + var engine = notification.Engine; + + var abpFunctions = new Dictionary(); + + var clockModel = new Dictionary + { + ["now"] = (Func)(() => _clock.Now), + ["normalize"] = (Func)((date) => _clock.Normalize(date)) + }; + abpFunctions["clock"] = clockModel; + + var currentTenantModel = new Dictionary + { + ["id"] = (Func)(() => _currentTenant.Id?.ToString()), + ["name"] = (Func)(() => _currentTenant.Name) + }; + abpFunctions["currentTenant"] = currentTenantModel; + + var utilsModel = new Dictionary + { + ["guid"] = (Func)(() => _guidGenerator.Create().ToString()) + }; + abpFunctions["utils"] = utilsModel; + + var localizationModel = new Dictionary + { + ["localize"] = ((Func)((key, resourceName) => + { + resourceName ??= LocalizationResourceNameAttribute.GetName(typeof(DefaultResource)); + IStringLocalizer? localizer = null; + + foreach (var resource in _localizationOptions.Resources.Values) + { + if (string.Equals(resourceName, resource.ResourceName, StringComparison.InvariantCultureIgnoreCase)) + { + localizer = _localizerFactory.Create(resource.ResourceType); + break; + } + } + + if (localizer == null) + { + return key; + } + + return localizer[key]; + })) + }; + abpFunctions["localization"] = localizationModel; + + var settingModel = new Dictionary + { + ["get"] = (Func)((name) => _settingProvider.GetOrNullAsync(name).GetAwaiter().GetResult()), + ["getNumber"] = (Func)((name) => _settingProvider.GetAsync(name, 0).GetAwaiter().GetResult()), + ["getBoolean"] = (Func)((name) => _settingProvider.GetAsync(name, false).GetAwaiter().GetResult()) + }; + abpFunctions["setting"] = settingModel; + + var authModel = new Dictionary + { + ["isGranted"] = (Func)((name) => _permissionChecker.IsGrantedAsync(name).GetAwaiter().GetResult()), + ["isAnyGranted"] = (Func)((names) => + { + var anyGrantResult = _permissionChecker.IsGrantedAsync(names).GetAwaiter().GetResult(); + + return !anyGrantResult.AllProhibited; + }), + ["areAllGranted"] = (Func)((names) => + { + var anyGrantResult = _permissionChecker.IsGrantedAsync(names).GetAwaiter().GetResult(); + + return anyGrantResult.AllGranted; + }) + }; + abpFunctions["auth"] = authModel; + + engine.SetValue("abp", abpFunctions); + + return Task.CompletedTask; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/ConfigureLiquidEngine.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/ConfigureLiquidEngine.cs new file mode 100644 index 000000000..72b4ea40b --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/ConfigureLiquidEngine.cs @@ -0,0 +1,63 @@ +using Elsa.Scripting.Liquid.Messages; +using Fluid; +using Fluid.Values; +using MediatR; +using Microsoft.Extensions.Localization; +using Microsoft.Extensions.Options; +using System.Threading; +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions; +using Volo.Abp.Guids; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Settings; +using Volo.Abp.Timing; + +namespace LINGYUN.Abp.Elsa.Scripting.Liquid; +public class ConfigureLiquidEngine : INotificationHandler +{ + private readonly IClock _clock; + private readonly ICurrentTenant _currentTenant; + private readonly AbpLocalizationOptions _localizationOptions; + private readonly IStringLocalizerFactory _localizerFactory; + private readonly IGuidGenerator _guidGenerator; + private readonly ISettingProvider _settingProvider; + private readonly IPermissionChecker _permissionChecker; + + public ConfigureLiquidEngine( + IClock clock, + ICurrentTenant currentTenant, + IOptions localizationOptions, + IStringLocalizerFactory localizerFactory, + IGuidGenerator guidGenerator, + ISettingProvider settingProvider, + IPermissionChecker permissionChecker) + { + _clock = clock; + _currentTenant = currentTenant; + _localizationOptions = localizationOptions.Value; + _localizerFactory = localizerFactory; + _guidGenerator = guidGenerator; + _settingProvider = settingProvider; + _permissionChecker = permissionChecker; + } + + public Task Handle(EvaluatingLiquidExpression notification, CancellationToken cancellationToken) + { + var context = notification.TemplateContext; + var options = context.Options; + + options.Scope.SetValue("Abp", new ObjectValue(new LiquidAbpAccessor())); + + options.MemberAccessStrategy.Register((_, name) => + { + return name switch + { + nameof(IClock.Now) => new DateTimeValue(_clock.Now), + _ => NilValue.Instance + }; + }); + + return Task.CompletedTask; + } +} diff --git a/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/LiquidAbpAccessor.cs b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/LiquidAbpAccessor.cs new file mode 100644 index 000000000..01a020516 --- /dev/null +++ b/aspnet-core/modules/elsa/LINGYUN.Abp.Elsa/LINGYUN/Abp/Elsa/Scripting/Liquid/LiquidAbpAccessor.cs @@ -0,0 +1,5 @@ +namespace LINGYUN.Abp.Elsa.Scripting.Liquid; + +public class LiquidAbpAccessor +{ +} diff --git a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs index ce98ee703..46dcf29c3 100644 --- a/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs +++ b/aspnet-core/services/LY.MicroService.WorkflowManagement.HttpApi.Host/WorkflowManagementHttpApiHostModule.Configure.cs @@ -159,14 +159,15 @@ public partial class WorkflowManagementHttpApiHostModule private void ConfigureEndpoints() { - Configure(options => - { - options.EndpointConfigureActions.Add( - (context) => - { - context.Endpoints.MapFallbackToPage("/_Host"); - }); - }); + // 不需要 + //Configure(options => + //{ + // options.EndpointConfigureActions.Add( + // (context) => + // { + // context.Endpoints.MapFallbackToPage("/_Host"); + // }); + //}); } private void ConfigureDistributedLock(IServiceCollection services, IConfiguration configuration)