40 changed files with 1137 additions and 100 deletions
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<AssemblyName>LINGYUN.Abp.ElsaNext.Server</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.ElsaNext.Server</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
<Nullable>Enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Elsa" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.CSharp" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Scheduling" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Workflows.Api" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.ElsaNext\LINGYUN.Abp.ElsaNext.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,41 @@ |
|||
using Elsa.Extensions; |
|||
using Elsa.Features.Services; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext.Server; |
|||
|
|||
[DependsOn(typeof(AbpElsaNextModule))] |
|||
public class AbpElsaNextServerModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IModule>(elsa => |
|||
{ |
|||
// see: https://v3.elsaworkflows.io/docs/installation/elsa-server
|
|||
|
|||
// Expose Elsa API endpoints.
|
|||
elsa.UseWorkflowsApi(); |
|||
|
|||
// Setup a SignalR hub for real-time updates from the server.
|
|||
elsa.UseRealTimeWorkflows(); |
|||
|
|||
// Enable C# workflow expressions
|
|||
elsa.UseCSharp(); |
|||
|
|||
// Enable Liquid workflow expressions.
|
|||
elsa.UseLiquid(); |
|||
|
|||
// Enable HTTP activities.
|
|||
elsa.UseHttp(); |
|||
|
|||
// Use timer activities.
|
|||
elsa.UseScheduling(); |
|||
|
|||
// Register custom activities from the application, if any.
|
|||
elsa.AddActivitiesFrom<AbpElsaNextServerModule>(); |
|||
|
|||
// Register custom workflows from the application, if any.
|
|||
elsa.AddWorkflowsFrom<AbpElsaNextServerModule>(); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,28 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<AssemblyName>LINGYUN.Abp.ElsaNext</AssemblyName> |
|||
<PackageId>LINGYUN.Abp.ElsaNext</PackageId> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace /> |
|||
<Nullable>Enable</Nullable> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.AutoMapper" /> |
|||
<PackageReference Include="Volo.Abp.Features" /> |
|||
<PackageReference Include="Volo.Abp.Guids" /> |
|||
<PackageReference Include="Volo.Abp.Timing" /> |
|||
<PackageReference Include="Volo.Abp.Threading" /> |
|||
<PackageReference Include="Volo.Abp.Json" /> |
|||
<!--<PackageReference Include="Elsa" VersionOverride="$(ElsaNextPackageVersion)" />--> |
|||
<PackageReference Include="Elsa" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,19 @@ |
|||
using Elsa.Workflows; |
|||
using Volo.Abp.Guids; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext; |
|||
|
|||
public class AbpElsaIdentityGenerator : IIdentityGenerator |
|||
{ |
|||
private readonly IGuidGenerator _guidGenerator; |
|||
|
|||
public AbpElsaIdentityGenerator(IGuidGenerator guidGenerator) |
|||
{ |
|||
_guidGenerator = guidGenerator; |
|||
} |
|||
|
|||
public string GenerateId() |
|||
{ |
|||
return _guidGenerator.Create().ToString("N"); |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
using AutoMapper; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext; |
|||
public class AbpElsaNextAutoMapperProfile : Profile |
|||
{ |
|||
public AbpElsaNextAutoMapperProfile() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using Elsa.Common.Features; |
|||
using Elsa.Common.Multitenancy; |
|||
using Elsa.Extensions; |
|||
using Elsa.Features.Services; |
|||
using Elsa.Tenants.Extensions; |
|||
using Elsa.Workflows; |
|||
using LINGYUN.Abp.ElsaNext.Localization; |
|||
using LINGYUN.Abp.ElsaNext.Multitenancy; |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Microsoft.Extensions.DependencyInjection.Extensions; |
|||
using Volo.Abp.AutoMapper; |
|||
using Volo.Abp.Features; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.Localization; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpAutoMapperModule), |
|||
typeof(AbpFeaturesModule), |
|||
typeof(AbpThreadingModule), |
|||
typeof(AbpJsonModule))] |
|||
public class AbpElsaNextModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
context.Services.AddScoped<ITenantResolver, AbpTenantResolver>(); |
|||
|
|||
var elsaModule = context.Services.GetPreConfigureActions<IModule>(); |
|||
|
|||
context.Services.AddElsa(elsa => |
|||
{ |
|||
elsa |
|||
.AddActivitiesFrom<AbpElsaNextModule>() |
|||
.AddWorkflowsFrom<AbpElsaNextModule>() |
|||
.UseTenants(tenants => |
|||
{ |
|||
tenants.ConfigureMultitenancy(options => |
|||
{ |
|||
options.TenantResolverPipelineBuilder.Append<AbpTenantResolver>(); |
|||
}); |
|||
}); |
|||
|
|||
elsa.Configure<MultitenancyFeature>(feature => |
|||
{ |
|||
feature.UseTenantsProvider<AbpTenantsProvider>(); |
|||
}); |
|||
|
|||
elsaModule.Configure(elsa); |
|||
}); |
|||
|
|||
context.Services.Replace( |
|||
ServiceDescriptor.Singleton<IIdentityGenerator, AbpElsaIdentityGenerator>()); |
|||
|
|||
Configure<AbpLocalizationOptions>(options => |
|||
{ |
|||
options.Resources.Add<ElsaNextResource>("en"); |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext.Localization; |
|||
|
|||
[LocalizationResourceName("ElsaNext")] |
|||
public class ElsaNextResource |
|||
{ |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Elsa.Common.Multitenancy; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext.Multitenancy; |
|||
public class AbpTenantResolver(ITenantConfigurationProvider tenantConfigurationProvider) : TenantResolverBase |
|||
{ |
|||
protected async override Task<TenantResolverResult> ResolveAsync(TenantResolverContext context) |
|||
{ |
|||
var tenant = await tenantConfigurationProvider.GetAsync(); |
|||
if (tenant == null) |
|||
{ |
|||
return Unresolved(); |
|||
} |
|||
|
|||
return AutoResolve(tenant.Id.ToString()); |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
using Elsa.Common.Multitenancy; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LINGYUN.Abp.ElsaNext.Multitenancy; |
|||
public class AbpTenantsProvider : ITenantsProvider |
|||
{ |
|||
private readonly ITenantStore _tenantStore; |
|||
public AbpTenantsProvider(ITenantStore tenantStore) |
|||
{ |
|||
_tenantStore = tenantStore; |
|||
} |
|||
|
|||
public async virtual Task<Tenant?> FindAsync(TenantFilter filter, CancellationToken cancellationToken = default) |
|||
{ |
|||
if (Guid.TryParse(filter.Id, out var tenantId)) |
|||
{ |
|||
var tenant = await _tenantStore.FindAsync(tenantId); |
|||
return tenant != null ? new Tenant |
|||
{ |
|||
Id = tenant.Id.ToString(), |
|||
Name = tenant.Name, |
|||
} : null; |
|||
} |
|||
return null; |
|||
} |
|||
|
|||
public async virtual Task<IEnumerable<Tenant>> ListAsync(CancellationToken cancellationToken = default) |
|||
{ |
|||
var tenants = await _tenantStore.GetListAsync(); |
|||
|
|||
return tenants.Select(tenant => new Tenant |
|||
{ |
|||
Id = tenant.Id.ToString(), |
|||
Name = tenant.Name |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
# LINGYUN.Abp.ElsaNext |
|||
|
|||
[elsa-core](https://github.com/elsa-workflows/elsa-core) 工作流的abp集成(3.x版本) |
|||
|
|||
## 特性 |
|||
|
|||
* 定义**AbpTenantResolver**与多租户集成,使elsa支持abp租户解析 |
|||
* 定义**AbpTenantsProvider**与多租户集成,使elsa从abp中取租户信息 |
|||
* 定义**AbpElsaIdGenerator**通过**IGuidGenerator**接口生成工作流标识 |
|||
* 定义**abp**相关JavaScript扩展 |
|||
|
|||
## 配置使用 |
|||
|
|||
```csharp |
|||
|
|||
[DependsOn( |
|||
typeof(AbpElsaNextModule) |
|||
)] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IModule>(elsa => |
|||
{ |
|||
// 自定义elsa相关配置 |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
@ -0,0 +1 @@ |
|||
elsa.sqlite.* |
|||
@ -0,0 +1,113 @@ |
|||
using Elsa.Expressions.Helpers; |
|||
using Elsa.Extensions; |
|||
using Elsa.Workflows; |
|||
using Elsa.Workflows.Memory; |
|||
using Elsa.Workflows.Models; |
|||
using Humanizer; |
|||
using System.Text.Json; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next; |
|||
|
|||
public class AbpActivityFactory : IActivityFactory |
|||
{ |
|||
public IActivity Create(Type type, ActivityConstructorContext context) |
|||
{ |
|||
// Backwards compatibility for older JSON schemas.
|
|||
var canStartWorkflow = GetBoolean(context.Element, "canStartWorkflow"); |
|||
var runAsynchronously = GetBoolean(context.Element, "runAsynchronously"); |
|||
var activityElement = context.Element; |
|||
var activityDescriptor = context.ActivityDescriptor; |
|||
var activity = (IActivity)context.Element.Deserialize(type, context.SerializerOptions)!; |
|||
var composite = activity as IComposite; |
|||
|
|||
composite?.Setup(); |
|||
|
|||
// TODO: 反序列化未创建默认值?
|
|||
if (activityDescriptor != null) |
|||
{ |
|||
ReadSyntheticInputs(activityDescriptor, activity, activityElement, context.SerializerOptions); |
|||
ReadSyntheticOutputs(activityDescriptor, activity, activityElement); |
|||
} |
|||
|
|||
activity.SetCanStartWorkflow(canStartWorkflow); |
|||
activity.SetRunAsynchronously(runAsynchronously); |
|||
|
|||
return activity; |
|||
} |
|||
|
|||
private void ReadSyntheticInputs(ActivityDescriptor activityDescriptor, IActivity activity, JsonElement activityRoot, JsonSerializerOptions options) |
|||
{ |
|||
foreach (var inputDescriptor in activityDescriptor.Inputs.Where(x => x.IsSynthetic)) |
|||
{ |
|||
var inputName = inputDescriptor.Name; |
|||
var propertyName = inputName.Camelize(); |
|||
var nakedType = inputDescriptor.Type; |
|||
var wrappedType = typeof(Input<>).MakeGenericType(nakedType); |
|||
|
|||
if (!activityRoot.TryGetProperty(propertyName, out var propertyElement) || propertyElement.ValueKind == JsonValueKind.Null || propertyElement.ValueKind == JsonValueKind.Undefined) |
|||
continue; |
|||
|
|||
var isWrapped = propertyElement.ValueKind == JsonValueKind.Object && propertyElement.GetProperty("typeName").ValueKind != JsonValueKind.Undefined; |
|||
|
|||
if (isWrapped) |
|||
{ |
|||
var json = propertyElement.ToString(); |
|||
var inputValue = JsonSerializer.Deserialize(json, wrappedType, options); |
|||
|
|||
activity.SyntheticProperties[inputName] = inputValue!; |
|||
} |
|||
else |
|||
{ |
|||
activity.SyntheticProperties[inputName] = propertyElement.ConvertTo(inputDescriptor.Type)!; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private void ReadSyntheticOutputs(ActivityDescriptor activityDescriptor, IActivity activity, JsonElement activityRoot) |
|||
{ |
|||
foreach (var outputDescriptor in activityDescriptor.Outputs.Where(x => x.IsSynthetic)) |
|||
{ |
|||
var outputName = outputDescriptor.Name; |
|||
var propertyName = outputName.Camelize(); |
|||
var nakedType = outputDescriptor.Type; |
|||
var wrappedType = typeof(Output<>).MakeGenericType(nakedType); |
|||
|
|||
if (!activityRoot.TryGetProperty(propertyName, out var propertyElement) || propertyElement.ValueKind == JsonValueKind.Null || propertyElement.ValueKind == JsonValueKind.Undefined) |
|||
continue; |
|||
|
|||
var memoryReferenceElement = propertyElement.GetProperty("memoryReference"); |
|||
|
|||
if (!memoryReferenceElement.TryGetProperty("id", out var memoryReferenceIdElement)) |
|||
continue; |
|||
|
|||
var variable = new Variable |
|||
{ |
|||
Id = memoryReferenceIdElement.GetString()! |
|||
}; |
|||
variable.Name = variable.Id; |
|||
|
|||
var output = Activator.CreateInstance(wrappedType, variable)!; |
|||
|
|||
activity.SyntheticProperties[outputName] = output!; |
|||
} |
|||
} |
|||
|
|||
private static bool GetBoolean(JsonElement element, string propertyName) |
|||
{ |
|||
var propertyNames = new[] { propertyName.Camelize(), propertyName.Pascalize() }; |
|||
|
|||
foreach (var name in propertyNames) |
|||
{ |
|||
if (element.TryGetProperty("customProperties", out var customPropertyElement)) |
|||
{ |
|||
if (customPropertyElement.TryGetProperty(name, out var canStartWorkflowElement)) |
|||
return canStartWorkflowElement.GetBoolean(); |
|||
} |
|||
|
|||
if (element.TryGetProperty(propertyName.Camelize(), out var property) && property.GetBoolean()) |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
using Elsa.Studio.Localization.Services; |
|||
using Microsoft.AspNetCore.Components; |
|||
using System.Globalization; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next; |
|||
|
|||
public class AbpBlazorServerCultureService(NavigationManager navigationManager) : ICultureService |
|||
{ |
|||
public Task ChangeCultureAsync(CultureInfo culture) |
|||
{ |
|||
if (CultureInfo.CurrentUICulture.Name != culture.Name) |
|||
{ |
|||
var cultureString = culture.Name; |
|||
var uri = new Uri(navigationManager.Uri).GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); |
|||
|
|||
// Set culture of the current thread.
|
|||
CultureInfo.CurrentCulture = culture; |
|||
CultureInfo.CurrentUICulture = culture; |
|||
var cultureEscaped = Uri.EscapeDataString(cultureString); |
|||
// var uriEscaped = Uri.EscapeDataString(uri);
|
|||
|
|||
navigationManager.NavigateTo( |
|||
$"Culture/Set?culture={cultureEscaped}&redirectUri=/", |
|||
forceLoad: true); |
|||
} |
|||
|
|||
return Task.CompletedTask; |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next.Controllers; |
|||
|
|||
public class HomeController : AbpControllerBase |
|||
{ |
|||
public IActionResult Index() |
|||
{ |
|||
return Redirect("/swagger/index.html"); |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk.Web"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net8.0</TargetFramework> |
|||
<Nullable>enable</Nullable> |
|||
<ImplicitUsings>enable</ImplicitUsings> |
|||
<RootNamespace>LY.MicroService.WorkflowManagement.Next</RootNamespace> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="AgileConfig.Client" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Serilog" /> |
|||
<!--<PackageReference Include="Volo.Abp.Caching.StackExchangeRedis" />--> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.MultiTenancy" /> |
|||
<PackageReference Include="Volo.Abp.AspNetCore.Authentication.JwtBearer" /> |
|||
<!--<PackageReference Include="Volo.Abp.AspNetCore.Mvc.NewtonsoftJson" />--> |
|||
<PackageReference Include="Volo.Abp.Autofac" /> |
|||
<PackageReference Include="Volo.Abp.Json" /> |
|||
<PackageReference Include="Volo.Abp.Swashbuckle" /> |
|||
<PackageReference Include="Volo.Abp.MailKit" /> |
|||
<!--<PackageReference Include="Volo.Abp.Http.Client.IdentityModel.Web" />--> |
|||
<!--<PackageReference Include="Volo.Abp.FeatureManagement.EntityFrameworkCore" /> |
|||
<PackageReference Include="Volo.Abp.PermissionManagement.EntityFrameworkCore" /> |
|||
<PackageReference Include="Volo.Abp.SettingManagement.EntityFrameworkCore" />--> |
|||
<!--<PackageReference Include="Microsoft.CodeAnalysis.Common" /> |
|||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" /> |
|||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools"> |
|||
<PrivateAssets>all</PrivateAssets> |
|||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
|||
</PackageReference>--> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Serilog.AspNetCore" /> |
|||
<PackageReference Include="Serilog.Enrichers.Environment" /> |
|||
<PackageReference Include="Serilog.Enrichers.Assembly" /> |
|||
<PackageReference Include="Serilog.Enrichers.Process" /> |
|||
<PackageReference Include="Serilog.Enrichers.Thread" /> |
|||
<PackageReference Include="Serilog.Settings.Configuration" /> |
|||
<PackageReference Include="Serilog.Sinks.Elasticsearch" /> |
|||
<PackageReference Include="Serilog.Sinks.File" /> |
|||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Elsa.EntityFrameworkCore" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.EntityFrameworkCore.Sqlite" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Identity" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Studio" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Studio.Core.BlazorServer" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Studio.Login.BlazorServer" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Studio.Localization.BlazorServer" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Studio.Translations" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
<PackageReference Include="Elsa.Api.Client" VersionOverride="$(ElsaNextPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\modules\elsa\LINGYUN.Abp.ElsaNext.Server\LINGYUN.Abp.ElsaNext.Server.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,61 @@ |
|||
@page "/" |
|||
@namespace LY.MicroService.WorkflowManagement.Next.Pages |
|||
|
|||
@inject IConfiguration Configuration; |
|||
@{ |
|||
var baseUrl = $"{Request.Scheme}://{Request.Host}"; |
|||
var apiUrl = baseUrl + Url.Content("~/elsa/api"); |
|||
var basePath = ""; |
|||
} |
|||
|
|||
<!DOCTYPE html> |
|||
<html lang="en"> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
|||
<base href="~/" /> |
|||
<link rel="apple-touch-icon" sizes="180x180" href="@basePath/_content/Elsa.Studio.Shell/apple-touch-icon.png"> |
|||
<link rel="icon" type="image/png" sizes="32x32" href="@basePath/_content/Elsa.Studio.Shell/favicon-32x32.png"> |
|||
<link rel="icon" type="image/png" sizes="16x16" href="@basePath/_content/Elsa.Studio.Shell/favicon-16x16.png"> |
|||
<link rel="manifest" href="@basePath/_content/Elsa.Studio.Shell/site.webmanifest"> |
|||
<link rel="preconnect" href="https://fonts.googleapis.com"> |
|||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> |
|||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" /> |
|||
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@300;400;500;700&display=swap" rel="stylesheet"> |
|||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700&display=swap" rel="stylesheet"> |
|||
<link href="https://fonts.googleapis.com/css2?family=Grandstander:wght@100&display=swap" rel="stylesheet"> |
|||
<link href="@basePath/_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" /> |
|||
<link href="@basePath/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.css" rel="stylesheet" /> |
|||
<link href="@basePath/_content/Radzen.Blazor/css/material-base.css" rel="stylesheet"> |
|||
<link href="@basePath/_content/Elsa.Studio.Shell/css/shell.css" rel="stylesheet"> |
|||
<link href="LY.MicroService.WorkflowManagement.Next.HttpApi.Host.styles.css" rel="stylesheet"> |
|||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> |
|||
</head> |
|||
<body> |
|||
<component type="typeof(App)" render-mode="ServerPrerendered" /> |
|||
|
|||
<div id="blazor-error-ui"> |
|||
<environment include="Staging,Production"> |
|||
An error has occurred. This application may no longer respond until reloaded. |
|||
</environment> |
|||
<environment include="Development"> |
|||
An unhandled exception has occurred. See browser dev tools for details. |
|||
</environment> |
|||
<a href="" class="reload">Reload</a> |
|||
<a class="dismiss">🗙</a> |
|||
</div> |
|||
<script src="@basePath/_content/BlazorMonaco/jsInterop.js"></script> |
|||
<script src="@basePath/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script> |
|||
<script src="@basePath/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script> |
|||
<script src="@basePath/_content/MudBlazor/MudBlazor.min.js"></script> |
|||
<script src="@basePath/_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script> |
|||
<script src="@basePath/_content/Radzen.Blazor/Radzen.Blazor.js"></script> |
|||
<script> |
|||
window.getClientConfig = function() { return { |
|||
"apiUrl": "@apiUrl", |
|||
"basePath": "@basePath" |
|||
} }; |
|||
</script> |
|||
<script src="@basePath/_framework/blazor.server.js"></script> |
|||
</body> |
|||
</html> |
|||
@ -0,0 +1,12 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Microsoft.AspNetCore.Mvc.RazorPages; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next.Pages |
|||
{ |
|||
public class _HostModel : PageModel |
|||
{ |
|||
public void OnGet() |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
@using Elsa.Studio.Shell |
|||
@using Microsoft.Extensions.Configuration |
|||
@using Microsoft.AspNetCore.Components.Web |
|||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers |
|||
@ -0,0 +1,89 @@ |
|||
using Elsa.Extensions; |
|||
using Elsa.Studio.Contracts; |
|||
using Elsa.Studio.Localization.BlazorServer.Extensions; |
|||
using LY.MicroService.WorkflowManagement.Next; |
|||
using Serilog; |
|||
using Volo.Abp.IO; |
|||
using Volo.Abp.Modularity.PlugIns; |
|||
|
|||
var builder = WebApplication.CreateBuilder(args); |
|||
|
|||
builder.Host.AddAppSettingsSecretsJson() |
|||
.UseAutofac() |
|||
.ConfigureAppConfiguration((context, config) => |
|||
{ |
|||
var agileConfigEnabled = context.Configuration["AgileConfig:IsEnabled"]; |
|||
if (context.Configuration.GetSection("AgileConfig").Exists() && |
|||
(agileConfigEnabled.IsNullOrWhiteSpace() || bool.Parse(agileConfigEnabled))) |
|||
{ |
|||
config.AddAgileConfig(new AgileConfig.Client.ConfigClient(context.Configuration)); |
|||
} |
|||
}) |
|||
.UseSerilog((context, provider, config) => |
|||
{ |
|||
config.ReadFrom.Configuration(context.Configuration); |
|||
}); |
|||
|
|||
await builder.AddApplicationAsync<WorkflowManagementNextHttpApiHostModule>(options => |
|||
{ |
|||
options.ApplicationName = "AbpElsaNextWebModule"; |
|||
// 从环境变量取用户机密配置, 适用于容器测试
|
|||
options.Configuration.UserSecretsId = Environment.GetEnvironmentVariable("APPLICATION_USER_SECRETS_ID"); |
|||
// 如果容器没有指定用户机密, 从项目读取
|
|||
options.Configuration.UserSecretsAssembly = typeof(WorkflowManagementNextHttpApiHostModule).Assembly; |
|||
// 搜索 Modules 目录下所有文件作为插件
|
|||
// 取消显示引用所有其他项目的模块,改为通过插件的形式引用
|
|||
var pluginFolder = Path.Combine(Directory.GetCurrentDirectory(), "Modules"); |
|||
|
|||
DirectoryHelper.CreateIfNotExists(pluginFolder); |
|||
|
|||
options.PlugInSources.AddFolder(pluginFolder, SearchOption.AllDirectories); |
|||
}); |
|||
|
|||
// Build the web application.
|
|||
var app = builder.Build(); |
|||
|
|||
await app.InitializeApplicationAsync(); |
|||
|
|||
// Run each startup task.
|
|||
var startupTaskRunner = app.Services.GetRequiredService<IStartupTaskRunner>(); |
|||
await startupTaskRunner.RunStartupTasksAsync(); |
|||
|
|||
// Configure web application's middleware pipeline.
|
|||
// Configure the HTTP request pipeline.
|
|||
if (!app.Environment.IsDevelopment()) |
|||
{ |
|||
app.UseResponseCompression(); |
|||
|
|||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
|||
app.UseHsts(); |
|||
} |
|||
|
|||
app.UseCors(); |
|||
app.UseForwardedHeaders(); |
|||
app.UseCorrelationId(); |
|||
app.UseElsaLocalization(); |
|||
app.UseStaticFiles(); |
|||
app.UseRouting(); // Required for SignalR.
|
|||
app.UseAuthentication(); |
|||
app.UseJwtTokenMiddleware(); |
|||
app.UseMultiTenancy(); |
|||
app.UseDynamicClaims(); |
|||
app.UseAuthorization(); |
|||
app.MapBlazorHub(); |
|||
app.UseWorkflowsApi(); // Use Elsa API endpoints.
|
|||
app.UseWorkflows(); // Use Elsa middleware to handle HTTP requests mapped to HTTP Endpoint activities.
|
|||
app.UseWorkflowsSignalRHubs(); // Optional SignalR integration. Elsa Studio uses SignalR to receive real-time updates from the server.
|
|||
app.UseSwagger(); |
|||
app.UseSwaggerUI(options => |
|||
{ |
|||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Support APP API"); |
|||
}); |
|||
|
|||
app.UseAuditing(); |
|||
app.UseAbpSerilogEnrichers(); |
|||
app.UseConfiguredEndpoints(); |
|||
|
|||
app.MapFallbackToPage("/_Host"); |
|||
|
|||
await app.RunAsync(); |
|||
@ -0,0 +1,22 @@ |
|||
{ |
|||
"$schema": "http://json.schemastore.org/launchsettings.json", |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:36683", |
|||
"sslPort": 0 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"http": { |
|||
"commandName": "Project", |
|||
"dotnetRunMessages": true, |
|||
"launchBrowser": false, |
|||
"applicationUrl": "http://127.0.0.1:30036", |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
using Microsoft.Extensions.Options; |
|||
using Microsoft.OpenApi.Models; |
|||
using Swashbuckle.AspNetCore.SwaggerGen; |
|||
using Volo.Abp.AspNetCore.MultiTenancy; |
|||
using Volo.Abp.MultiTenancy; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next; |
|||
|
|||
public class TenantHeaderParamter : IOperationFilter |
|||
{ |
|||
private readonly AbpMultiTenancyOptions _multiTenancyOptions; |
|||
private readonly AbpAspNetCoreMultiTenancyOptions _aspNetCoreMultiTenancyOptions; |
|||
public TenantHeaderParamter( |
|||
IOptions<AbpMultiTenancyOptions> multiTenancyOptions, |
|||
IOptions<AbpAspNetCoreMultiTenancyOptions> aspNetCoreMultiTenancyOptions) |
|||
{ |
|||
_multiTenancyOptions = multiTenancyOptions.Value; |
|||
_aspNetCoreMultiTenancyOptions = aspNetCoreMultiTenancyOptions.Value; |
|||
} |
|||
|
|||
public void Apply(OpenApiOperation operation, OperationFilterContext context) |
|||
{ |
|||
if (_multiTenancyOptions.IsEnabled) |
|||
{ |
|||
operation.Parameters = operation.Parameters ?? new List<OpenApiParameter>(); |
|||
operation.Parameters.Add(new OpenApiParameter |
|||
{ |
|||
Name = _aspNetCoreMultiTenancyOptions.TenantKey, |
|||
In = ParameterLocation.Header, |
|||
Description = "Tenant Id/Name in http header", |
|||
Required = false |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,147 @@ |
|||
using Elsa.EntityFrameworkCore.Extensions; |
|||
using Elsa.EntityFrameworkCore.Modules.Management; |
|||
using Elsa.EntityFrameworkCore.Modules.Runtime; |
|||
using Elsa.Extensions; |
|||
using Elsa.Features.Services; |
|||
using Elsa.Studio.Dashboard.Extensions; |
|||
using Elsa.Studio.Extensions; |
|||
using Elsa.Studio.Localization.BlazorServer.Extensions; |
|||
using Elsa.Studio.Localization.BlazorServer.Services; |
|||
using Elsa.Studio.Localization.Models; |
|||
using Elsa.Studio.Localization.Services; |
|||
using Elsa.Studio.Login.BlazorServer.Extensions; |
|||
using Elsa.Studio.Login.HttpMessageHandlers; |
|||
using Elsa.Studio.Models; |
|||
using Elsa.Studio.Shell.Extensions; |
|||
using Elsa.Studio.Translations; |
|||
using Elsa.Studio.Workflows.Designer.Extensions; |
|||
using Elsa.Studio.Workflows.Extensions; |
|||
using Elsa.Workflows; |
|||
using LINGYUN.Abp.ElsaNext.Server; |
|||
using Microsoft.OpenApi.Models; |
|||
using Volo.Abp.AspNetCore.Authentication.JwtBearer; |
|||
using Volo.Abp.AspNetCore.MultiTenancy; |
|||
using Volo.Abp.AspNetCore.Serilog; |
|||
using Volo.Abp.Autofac; |
|||
using Volo.Abp.Json; |
|||
using Volo.Abp.MailKit; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Swashbuckle; |
|||
|
|||
namespace LY.MicroService.WorkflowManagement.Next; |
|||
|
|||
[DependsOn(typeof(AbpElsaNextServerModule))] |
|||
[DependsOn(typeof(AbpAspNetCoreSerilogModule))] |
|||
[DependsOn(typeof(AbpAspNetCoreMultiTenancyModule))] |
|||
[DependsOn(typeof(AbpAspNetCoreAuthenticationJwtBearerModule))] |
|||
[DependsOn(typeof(AbpJsonModule))] |
|||
[DependsOn(typeof(AbpSwashbuckleModule))] |
|||
[DependsOn(typeof(AbpMailKitModule))] |
|||
[DependsOn(typeof(AbpAutofacModule))] |
|||
public class WorkflowManagementNextHttpApiHostModule : AbpModule |
|||
{ |
|||
public override void PreConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
PreConfigure<IModule>(elsa => |
|||
{ |
|||
// Configure Management layer to use EF Core.
|
|||
elsa.UseWorkflowManagement(management => management.UseEntityFrameworkCore(ef => ef.UseSqlite())); |
|||
|
|||
// Configure Runtime layer to use EF Core.
|
|||
elsa.UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore(ef => ef.UseSqlite())); |
|||
|
|||
// Default Identity features for authentication/authorization.
|
|||
elsa.UseIdentity(identity => |
|||
{ |
|||
identity.TokenOptions = options => options.SigningKey = "sufficiently-large-secret-signing-key"; // This key needs to be at least 256 bits long.
|
|||
identity.UseAdminUserProvider(); |
|||
}); |
|||
|
|||
// Configure ASP.NET authentication/authorization.
|
|||
elsa.UseDefaultAuthentication(auth => auth.UseAdminApiKey()); |
|||
}); |
|||
} |
|||
|
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
// Register Razor services.
|
|||
context.Services.AddRazorPages(); |
|||
|
|||
context.Services.AddCoreInternal(); |
|||
context.Services.AddSharedServices(); |
|||
context.Services.AddTranslations(); |
|||
|
|||
context.Services.AddServerSideBlazor(options => |
|||
{ |
|||
// Register the root components.
|
|||
options.RootComponents.RegisterCustomElsaStudioElements(); |
|||
}); |
|||
// Register shell services and modules.
|
|||
var backendApiConfig = new BackendApiConfig |
|||
{ |
|||
ConfigureBackendOptions = options => configuration.GetSection("Backend").Bind(options), |
|||
ConfigureHttpClientBuilder = options => options.AuthenticationHandler = typeof(AuthenticatingApiHttpMessageHandler), |
|||
}; |
|||
context.Services.AddShell(options => configuration.GetSection("Shell").Bind(options)); |
|||
context.Services.AddRemoteBackend(backendApiConfig); |
|||
context.Services.AddLoginModule(); |
|||
context.Services.AddDashboardModule(); |
|||
context.Services.AddWorkflowsModule(); |
|||
context.Services.AddLocalizationModule(new LocalizationConfig |
|||
{ |
|||
ConfigureLocalizationOptions = options => configuration.GetSection("Localization").Bind(options), |
|||
}); |
|||
// Configure SignalR.
|
|||
context.Services.AddSignalR(options => |
|||
{ |
|||
// Set MaximumReceiveMessageSize to handle large workflows.
|
|||
options.MaximumReceiveMessageSize = 5 * 1024 * 1000; // 5MB
|
|||
}); |
|||
|
|||
// Add Health Checks.
|
|||
context.Services.AddHealthChecks(); |
|||
|
|||
|
|||
// Configure CORS to allow designer app hosted on a different origin to invoke the APIs.
|
|||
context.Services.AddCors(cors => cors |
|||
.AddDefaultPolicy(policy => policy |
|||
.AllowAnyOrigin() // For demo purposes only. Use a specific origin instead.
|
|||
.AllowAnyHeader() |
|||
.AllowAnyMethod() |
|||
.WithExposedHeaders("x-elsa-workflow-instance-id"))); |
|||
|
|||
// Swagger
|
|||
context.Services.AddSwaggerGen( |
|||
options => |
|||
{ |
|||
options.SwaggerDoc("v1", new OpenApiInfo { Title = "Workflow API", Version = "v1" }); |
|||
options.DocInclusionPredicate((docName, description) => true); |
|||
options.CustomSchemaIds(type => type.FullName); |
|||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme |
|||
{ |
|||
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"", |
|||
Name = "Authorization", |
|||
In = ParameterLocation.Header, |
|||
Scheme = "bearer", |
|||
Type = SecuritySchemeType.Http, |
|||
BearerFormat = "JWT" |
|||
}); |
|||
options.AddSecurityRequirement(new OpenApiSecurityRequirement |
|||
{ |
|||
{ |
|||
new OpenApiSecurityScheme |
|||
{ |
|||
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } |
|||
}, |
|||
new string[] { } |
|||
} |
|||
}); |
|||
options.OperationFilter<TenantHeaderParamter>(); |
|||
}); |
|||
|
|||
context.Services.AddTransient<AuthenticatingApiHttpMessageHandler>(); |
|||
context.Services.AddSingleton<IActivityFactory, AbpActivityFactory>(); |
|||
context.Services.AddScoped<ICultureService, AbpBlazorServerCultureService>(); |
|||
} |
|||
} |
|||
@ -0,0 +1,76 @@ |
|||
{ |
|||
"DetailedErrors": true, |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Debug", |
|||
"Microsoft": "Debug" |
|||
} |
|||
}, |
|||
"Serilog": { |
|||
"MinimumLevel": { |
|||
"Default": "Information", |
|||
"Override": { |
|||
"Microsoft.AspNetCore.Routing": "Debug", |
|||
"System": "Information", |
|||
"Microsoft": "Information" |
|||
} |
|||
}, |
|||
"Enrich": [ "FromLogContext", "WithProcessId", "WithThreadId", "WithEnvironmentName", "WithMachineName", "WithApplicationName", "WithUniqueId" ], |
|||
"WriteTo": [ |
|||
{ |
|||
"Name": "Console", |
|||
"Args": { |
|||
"initialMinimumLevel": "Verbose", |
|||
"standardErrorFromLevel": "Verbose", |
|||
"restrictedToMinimumLevel": "Verbose", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
}, |
|||
{ |
|||
"Name": "File", |
|||
"Args": { |
|||
"path": "Logs/Debug-.log", |
|||
"restrictedToMinimumLevel": "Debug", |
|||
"rollingInterval": "Day", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
}, |
|||
{ |
|||
"Name": "File", |
|||
"Args": { |
|||
"path": "Logs/Info-.log", |
|||
"restrictedToMinimumLevel": "Information", |
|||
"rollingInterval": "Day", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
}, |
|||
{ |
|||
"Name": "File", |
|||
"Args": { |
|||
"path": "Logs/Warn-.log", |
|||
"restrictedToMinimumLevel": "Warning", |
|||
"rollingInterval": "Day", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
}, |
|||
{ |
|||
"Name": "File", |
|||
"Args": { |
|||
"path": "Logs/Error-.log", |
|||
"restrictedToMinimumLevel": "Error", |
|||
"rollingInterval": "Day", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
}, |
|||
{ |
|||
"Name": "File", |
|||
"Args": { |
|||
"path": "Logs/Fatal-.log", |
|||
"restrictedToMinimumLevel": "Fatal", |
|||
"rollingInterval": "Day", |
|||
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] [{SourceContext}] [{ProcessId}] [{ThreadId}] - {Message:lj}{NewLine}{Exception}" |
|||
} |
|||
} |
|||
] |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
{ |
|||
"Logging": { |
|||
"LogLevel": { |
|||
"Default": "Information", |
|||
"Microsoft.AspNetCore": "Warning" |
|||
} |
|||
}, |
|||
"AllowedHosts": "*", |
|||
"Backend": { |
|||
"Url": "http://localhost:30036/elsa/api" |
|||
}, |
|||
"Hosting": { |
|||
"BaseUrl": "http://localhost:30036", |
|||
"BasePath": "/api/workflows" |
|||
}, |
|||
"Localization": { |
|||
"SupportedCultures": [ |
|||
"ar", |
|||
"de", |
|||
"fa", |
|||
"fr", |
|||
"nl", |
|||
"pt", |
|||
"uk", |
|||
"zh-Hans", |
|||
"zh-Hant" |
|||
] |
|||
} |
|||
} |
|||
Loading…
Reference in new issue