From 610b0511bdad88647709c80ec024b1e5be5f71d2 Mon Sep 17 00:00:00 2001
From: cKey <35512826+colinin@users.noreply.github.com>
Date: Sun, 4 Oct 2020 16:18:30 +0800
Subject: [PATCH] create a rule engine module
---
aspnet-core/LINGYUN.MicroService.sln | 20 +++-
.../LINGYUN.Abp.Rules.csproj | 14 +++
.../LINGYUN/Abp/Rules/AbpRulesEngineModule.cs | 16 ++++
.../Rules/EntityChangedRulesInterceptor.cs | 48 ++++++++++
.../EntityChangedRulesInterceptorRegistrar.cs | 28 ++++++
.../LINGYUN/Abp/Rules/EntityRuleContext.cs | 18 ++++
.../LINGYUN/Abp/Rules/ErrorType.cs | 8 ++
.../LINGYUN/Abp/Rules/ExpressionType.cs | 7 ++
.../Abp/Rules/IEntityRuleContributor.cs | 9 ++
.../LINGYUN/Abp/Rules/INeedRule.cs | 6 ++
.../LINGYUN/Abp/Rules/IRuleFinder.cs | 11 +++
.../Abp/Rules/NullEntityRuleContributor.cs | 13 +++
.../LINGYUN/Abp/Rules/NullRuleFinder.cs | 15 +++
.../LINGYUN/Abp/Rules/Rule.cs | 90 ++++++++++++++++++
.../LINGYUN/Abp/Rules/RuleGroup.cs | 39 ++++++++
.../LINGYUN/Abp/Rules/RuleParam.cs | 43 +++++++++
.../common/LINGYUN.Abp.Rules/README.md | 7 ++
.../LINGYUN.Abp.RulesEngine.csproj | 19 ++++
.../Abp/RulesEngine/AbpMsRulesEngineModule.cs | 22 +++++
.../RulesEngine/MsEntityRuleContributor.cs | 50 ++++++++++
.../RulesEngine/MsRulesEngineMapperProfile.cs | 27 ++++++
.../common/LINGYUN.Abp.RulesEngine/README.md | 7 ++
.../LINGYUN.ApiGateway.Host/event-bus-cap.db | Bin 32768 -> 32768 bytes
docker-compose.yml | 5 +-
vueJs/src/api/auditing.ts | 2 +-
.../views/admin/auditing/audit-log/index.vue | 2 +-
.../admin/auditing/security-log/index.vue | 2 +-
27 files changed, 518 insertions(+), 10 deletions(-)
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN.Abp.Rules.csproj
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/AbpRulesEngineModule.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptor.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptorRegistrar.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityRuleContext.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ErrorType.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ExpressionType.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IEntityRuleContributor.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/INeedRule.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IRuleFinder.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullEntityRuleContributor.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullRuleFinder.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.Rules/README.md
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN.Abp.RulesEngine.csproj
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpMsRulesEngineModule.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs
create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md
diff --git a/aspnet-core/LINGYUN.MicroService.sln b/aspnet-core/LINGYUN.MicroService.sln
index 38cb09383..2bb914e1a 100644
--- a/aspnet-core/LINGYUN.MicroService.sln
+++ b/aspnet-core/LINGYUN.MicroService.sln
@@ -233,11 +233,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Features.Client
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "auditing", "auditing", "{67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Auditing.Application.Contracts", "modules\auditing\LINGYUN.Abp.Auditing.Application.Contracts\LINGYUN.Abp.Auditing.Application.Contracts.csproj", "{F40F88F1-CA90-4A79-B772-80E287E25982}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Auditing.Application.Contracts", "modules\auditing\LINGYUN.Abp.Auditing.Application.Contracts\LINGYUN.Abp.Auditing.Application.Contracts.csproj", "{F40F88F1-CA90-4A79-B772-80E287E25982}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Auditing.Application", "modules\auditing\LINGYUN.Abp.Auditing.Application\LINGYUN.Abp.Auditing.Application.csproj", "{AC3C8985-73C2-472A-8E76-A0B8786FEC3F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Auditing.Application", "modules\auditing\LINGYUN.Abp.Auditing.Application\LINGYUN.Abp.Auditing.Application.csproj", "{AC3C8985-73C2-472A-8E76-A0B8786FEC3F}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Auditing.HttpApi", "modules\auditing\LINGYUN.Abp.Auditing.HttpApi\LINGYUN.Abp.Auditing.HttpApi.csproj", "{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Auditing.HttpApi", "modules\auditing\LINGYUN.Abp.Auditing.HttpApi\LINGYUN.Abp.Auditing.HttpApi.csproj", "{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Rules", "modules\common\LINGYUN.Abp.Rules\LINGYUN.Abp.Rules.csproj", "{8ACB30CF-2311-4C0A-AE79-92C1A7667353}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.RulesEngine", "modules\common\LINGYUN.Abp.RulesEngine\LINGYUN.Abp.RulesEngine.csproj", "{FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -633,6 +637,14 @@ Global
{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8ACB30CF-2311-4C0A-AE79-92C1A7667353}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -753,6 +765,8 @@ Global
{F40F88F1-CA90-4A79-B772-80E287E25982} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
{AC3C8985-73C2-472A-8E76-A0B8786FEC3F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
{07E19CA8-671D-4D58-9FED-5FEE9AE01A2F} = {67DAB2A0-D407-4CAB-8414-AE3D0AC52FC4}
+ {8ACB30CF-2311-4C0A-AE79-92C1A7667353} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
+ {FD007B55-A0F1-4EF8-9CFD-6D8AD1B61B65} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN.Abp.Rules.csproj b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN.Abp.Rules.csproj
new file mode 100644
index 000000000..44dc17105
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN.Abp.Rules.csproj
@@ -0,0 +1,14 @@
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/AbpRulesEngineModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/AbpRulesEngineModule.cs
new file mode 100644
index 000000000..c19f6df37
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/AbpRulesEngineModule.cs
@@ -0,0 +1,16 @@
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.Domain;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.Rules
+{
+ [DependsOn(
+ typeof(AbpDddDomainModule))]
+ public class AbpRulesEngineModule : AbpModule
+ {
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.OnRegistred(EntityChangedRulesInterceptorRegistrar.RegisterIfNeeded);
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptor.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptor.cs
new file mode 100644
index 000000000..948dde25f
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptor.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Linq;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.DynamicProxy;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class EntityChangedRulesInterceptor : AbpInterceptor, ITransientDependency
+ {
+ protected IRuleFinder RuleFinder { get; }
+ protected IEntityRuleContributor EntityRuleContributor { get; }
+
+ public EntityChangedRulesInterceptor(
+ IRuleFinder ruleFinder,
+ IEntityRuleContributor entityRuleContributor)
+ {
+ RuleFinder = ruleFinder;
+ EntityRuleContributor = entityRuleContributor;
+ }
+
+ public override async Task InterceptAsync(IAbpMethodInvocation invocation)
+ {
+ var entityObj = invocation.Arguments.First();
+ // TODO: 针对实体的变更执行一次定义的规则
+ // IBasicRepository.InsertAsync || IBasicRepository.UpdateAsync || IBasicRepository.DeleteAsync
+ if (entityObj != null && entityObj is IEntity entity)
+ {
+ await ApplyEntityRuleAsync(entity);
+ }
+
+ await invocation.ProceedAsync();
+ }
+
+ protected virtual async Task ApplyEntityRuleAsync(IEntity entity)
+ {
+ Type entityType = ProxyHelper.GetUnProxiedType(entity);
+ // 加载规则列表
+ var groups = await RuleFinder.GetRuleGroupsAsync(entityType);
+ if (groups.Any())
+ {
+ // 应用规则
+ await EntityRuleContributor.ApplyAsync(new EntityRuleContext(groups, entity));
+ }
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptorRegistrar.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptorRegistrar.cs
new file mode 100644
index 000000000..3b7b11a4e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityChangedRulesInterceptorRegistrar.cs
@@ -0,0 +1,28 @@
+using System;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.DynamicProxy;
+
+namespace LINGYUN.Abp.Rules
+{
+ public static class EntityChangedRulesInterceptorRegistrar
+ {
+ public static void RegisterIfNeeded(IOnServiceRegistredContext context)
+ {
+ if (ShouldIntercept(context.ImplementationType))
+ {
+ context.Interceptors.TryAdd();
+ }
+ }
+
+ private static bool ShouldIntercept(Type type)
+ {
+ // 拦截器的要求
+ // 1、继承自IBasicRepository的仓储
+ // 2、继承自INeedRule接口的实体
+ return !DynamicProxyIgnoreTypes.Contains(type) &&
+ type.IsAssignableTo(typeof(IBasicRepository<>)) &&
+ type.GetGenericTypeDefinition().IsAssignableTo(typeof(INeedRule));
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityRuleContext.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityRuleContext.cs
new file mode 100644
index 000000000..58bbd744e
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/EntityRuleContext.cs
@@ -0,0 +1,18 @@
+using System.Collections.Generic;
+using Volo.Abp.Domain.Entities;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class EntityRuleContext
+ {
+ public List Groups { get; }
+ public IEntity Entity { get; }
+ public EntityRuleContext(
+ List groups,
+ IEntity entity)
+ {
+ Groups = groups;
+ Entity = entity;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ErrorType.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ErrorType.cs
new file mode 100644
index 000000000..6b5825435
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ErrorType.cs
@@ -0,0 +1,8 @@
+namespace LINGYUN.Abp.Rules
+{
+ public enum ErrorType
+ {
+ Warning = 0,
+ Error = 1
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ExpressionType.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ExpressionType.cs
new file mode 100644
index 000000000..49fb8dcc1
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/ExpressionType.cs
@@ -0,0 +1,7 @@
+namespace LINGYUN.Abp.Rules
+{
+ public enum ExpressionType
+ {
+ LambdaExpression = 0
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IEntityRuleContributor.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IEntityRuleContributor.cs
new file mode 100644
index 000000000..badbd75ff
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IEntityRuleContributor.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Rules
+{
+ public interface IEntityRuleContributor
+ {
+ Task ApplyAsync(EntityRuleContext context);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/INeedRule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/INeedRule.cs
new file mode 100644
index 000000000..7a1faab36
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/INeedRule.cs
@@ -0,0 +1,6 @@
+namespace LINGYUN.Abp.Rules
+{
+ public interface INeedRule
+ {
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IRuleFinder.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IRuleFinder.cs
new file mode 100644
index 000000000..ee3f61064
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/IRuleFinder.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace LINGYUN.Abp.Rules
+{
+ public interface IRuleFinder
+ {
+ Task> GetRuleGroupsAsync(Type entityType);
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullEntityRuleContributor.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullEntityRuleContributor.cs
new file mode 100644
index 000000000..52a170c94
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullEntityRuleContributor.cs
@@ -0,0 +1,13 @@
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class NullEntityRuleContributor : IEntityRuleContributor, ISingletonDependency
+ {
+ public Task ApplyAsync(EntityRuleContext context)
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullRuleFinder.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullRuleFinder.cs
new file mode 100644
index 000000000..81aaa79cc
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/NullRuleFinder.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class NullRuleFinder : IRuleFinder, ISingletonDependency
+ {
+ public Task> GetRuleGroupsAsync(Type entityType)
+ {
+ return Task.FromResult(new List());
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs
new file mode 100644
index 000000000..f35e5b054
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/Rule.cs
@@ -0,0 +1,90 @@
+using JetBrains.Annotations;
+using System;
+using System.Collections.Generic;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.Rules
+{
+ ///
+ /// ref: https://github.com/microsoft/RulesEngine/blob/master/src/RulesEngine/RulesEngine/Models/Rule.cs
+ ///
+ public class Rule
+ {
+ [NotNull]
+ public string Name { get; }
+ public string Operator { get; }
+ public string ErrorMessage { get; }
+ public DateTime CreationTime { get; }
+ public ErrorType ErrorType { get; }
+ public ExpressionType? ExpressionType { get; }
+ public List Rules { get; }
+ public List InjectRules { get; }
+ public List Params { get; }
+ public string Expression { get; }
+ public string SuccessEvent { get; }
+
+ public Rule(
+ [NotNull] string name,
+ string @operator,
+ DateTime creationTime,
+ string expression = null,
+ string successEvent = null,
+ ErrorType errorType = ErrorType.Warning,
+ ExpressionType? expressionType = null)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+
+ Name = name;
+ Operator = @operator;
+ CreationTime = creationTime;
+ Expression = expression;
+ SuccessEvent = successEvent;
+ ErrorType = errorType;
+ ExpressionType = expressionType;
+
+ Rules = new List();
+ Params = new List();
+ InjectRules = new List();
+ }
+
+ public Rule CreateChildren(Rule rule)
+ {
+ Rules.Add(rule);
+
+ return this;
+ }
+
+ public Rule WithParam(RuleParam param)
+ {
+ Params.AddIfNotContains(param);
+ return this;
+ }
+
+ public Rule InjectRule(string ruleName)
+ {
+ InjectRules.AddIfNotContains(ruleName);
+
+ return this;
+ }
+
+ public override int GetHashCode()
+ {
+ return Name.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (obj is Rule rule)
+ {
+ return rule.Name.Equals(Name);
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs
new file mode 100644
index 000000000..c6447a204
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleGroup.cs
@@ -0,0 +1,39 @@
+using JetBrains.Annotations;
+using System.Collections.Generic;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class RuleGroup
+ {
+ [NotNull]
+ public string Name { get; }
+ public List InjectRules { get; }
+ public List Rules { get; }
+
+ public RuleGroup(
+ [NotNull] string name)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+
+ Name = name;
+
+ Rules = new List();
+ InjectRules = new List();
+ }
+
+ public RuleGroup InjectRule(string ruleName)
+ {
+ InjectRules.AddIfNotContains(ruleName);
+
+ return this;
+ }
+
+ public RuleGroup WithRule(Rule rule)
+ {
+ Rules.AddIfNotContains(rule);
+
+ return this;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs
new file mode 100644
index 000000000..2601e4c47
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/LINGYUN/Abp/Rules/RuleParam.cs
@@ -0,0 +1,43 @@
+using JetBrains.Annotations;
+using Volo.Abp;
+
+namespace LINGYUN.Abp.Rules
+{
+ public class RuleParam
+ {
+ [NotNull]
+ public string Name { get; }
+
+ [NotNull]
+ public string Expression { get; }
+ public RuleParam(
+ [NotNull] string name,
+ [NotNull] string expression)
+ {
+ Check.NotNullOrWhiteSpace(name, nameof(name));
+ Check.NotNullOrWhiteSpace(expression, nameof(expression));
+
+ Name = name;
+ Expression = expression;
+ }
+
+ public override int GetHashCode()
+ {
+ return Name.GetHashCode();
+ }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (obj is RuleParam param)
+ {
+ return param.Name.Equals(Name);
+ }
+ return base.Equals(obj);
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.Rules/README.md b/aspnet-core/modules/common/LINGYUN.Abp.Rules/README.md
new file mode 100644
index 000000000..b37832f46
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.Rules/README.md
@@ -0,0 +1,7 @@
+# LINGYUN.Abp.Rules
+
+规则引擎定义
+
+## 配置使用
+
+待完善
\ No newline at end of file
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN.Abp.RulesEngine.csproj b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN.Abp.RulesEngine.csproj
new file mode 100644
index 000000000..093bd2658
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN.Abp.RulesEngine.csproj
@@ -0,0 +1,19 @@
+
+
+
+
+
+ netstandard2.0
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpMsRulesEngineModule.cs b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpMsRulesEngineModule.cs
new file mode 100644
index 000000000..f56421321
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/AbpMsRulesEngineModule.cs
@@ -0,0 +1,22 @@
+using LINGYUN.Abp.Rules;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.AutoMapper;
+using Volo.Abp.Modularity;
+
+namespace LINGYUN.Abp.RulesEngine
+{
+ [DependsOn(
+ typeof(AbpRulesEngineModule),
+ typeof(AbpAutoMapperModule))]
+ public class AbpMsRulesEngineModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ context.Services.AddAutoMapperObjectMapper();
+ Configure(options =>
+ {
+ options.AddProfile(validate: true);
+ });
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs
new file mode 100644
index 000000000..b59b621bb
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsEntityRuleContributor.cs
@@ -0,0 +1,50 @@
+using LINGYUN.Abp.Rules;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using RulesEngine.Extensions;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+using Volo.Abp.ObjectMapping;
+using MsRulesEngine = RulesEngine.RulesEngine;
+using MsWorkflowRules = RulesEngine.Models.WorkflowRules;
+
+namespace LINGYUN.Abp.RulesEngine
+{
+ [Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
+ [ExposeServices(typeof(IEntityRuleContributor))]
+ public class MsEntityRuleContributor : IEntityRuleContributor
+ {
+ protected ILogger Logger { get; }
+ protected IObjectMapper ObjectMapper { get; }
+ public MsEntityRuleContributor(
+ IObjectMapper objectMapper,
+ ILogger logger)
+ {
+ Logger = logger;
+ ObjectMapper = objectMapper;
+ }
+
+ public Task ApplyAsync(EntityRuleContext context)
+ {
+ var workflowRules = ObjectMapper.Map, List>(context.Groups);
+
+ var rulesEngine = new MsRulesEngine(workflowRules.ToArray(), Logger);
+
+ foreach(var workflow in workflowRules)
+ {
+ var ruleRsults = rulesEngine.ExecuteRule(workflow.WorkflowName, context.Entity);
+ ruleRsults.OnSuccess((eventName) =>
+ {
+ Logger.LogDebug($"{workflow.WorkflowName} evaluation resulted in succees - {eventName}");
+ });
+ ruleRsults.OnFail(() =>
+ {
+ Logger.LogWarning($"{workflow.WorkflowName} evaluation resulted in failure");
+ });
+ }
+
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs
new file mode 100644
index 000000000..deffe9a2f
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/LINGYUN/Abp/RulesEngine/MsRulesEngineMapperProfile.cs
@@ -0,0 +1,27 @@
+using AutoMapper;
+using LINGYUN.Abp.Rules;
+using MsExpressionType = RulesEngine.Models.RuleExpressionType;
+using MsRule = RulesEngine.Models.Rule;
+using MsRuleErrorType = RulesEngine.Models.ErrorType;
+using MsRuleParam = RulesEngine.Models.LocalParam;
+using MsWorkflowRules = RulesEngine.Models.WorkflowRules;
+
+namespace LINGYUN.Abp.RulesEngine
+{
+ public class MsRulesEngineMapperProfile : Profile
+ {
+ public MsRulesEngineMapperProfile()
+ {
+ CreateMap();
+ CreateMap()
+ .ForMember(r => r.LocalParams, map => map.MapFrom(m => m.Params))
+ .ForMember(r => r.WorkflowRulesToInject, map => map.MapFrom(m => m.InjectRules))
+ .ForMember(r => r.ErrorType, map => map.MapFrom(m => (MsRuleErrorType)m.ErrorType.GetHashCode()))
+ .ForMember(r => r.RuleExpressionType, map => map.MapFrom(m => (MsExpressionType)m.ExpressionType.GetHashCode()));
+ CreateMap()
+ .ForMember(wr => wr.WorkflowName, map => map.MapFrom(m => m.Name))
+ .ForMember(wr => wr.Rules, map => map.MapFrom(m => m.Rules))
+ .ForMember(wr => wr.WorkflowRulesToInject, map => map.MapFrom(m => m.InjectRules));
+ }
+ }
+}
diff --git a/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md
new file mode 100644
index 000000000..b50241c85
--- /dev/null
+++ b/aspnet-core/modules/common/LINGYUN.Abp.RulesEngine/README.md
@@ -0,0 +1,7 @@
+# LINGYUN.Abp.RulesEngine
+
+规则引擎 [microsoft/RulesEngine](https://github.com/microsoft/RulesEngine) (RulesEngine) 实现
+
+## 配置使用
+
+待完善
\ No newline at end of file
diff --git a/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db b/aspnet-core/services/apigateway/LINGYUN.ApiGateway.Host/event-bus-cap.db
index 5eb62e8538e51e6f1a1a16a7f1d0c18f3bf45561..cf34328b79d32a17a79c28167582b02a6a21d143 100644
GIT binary patch
delta 227
zcmZo@U}|V!njp>V$-uzC0maM{HOv`3Hzq9L=i>zmF$gd)a4LY{W*
zU)gC@3mDjd90wu&$8tu$7BH{^ImSZzkAC@BEnomz!=MJ_e2M^an1LM0&9C*v6!^Kb
v8CaMcfDU52%F@N;uvs7=nj5GV=#>2E86uoaK$Rdv**7*SF>N*~I>!qD$+I&@
delta 230
zcmZo@U}|V!njp>V#=yY90mY0HHOv{^HYP0K=VJv5G4lTgk__zpzc=#<2yt#!i1cP+
zX>n)b*_%=4uRK&){#s7tYjei*f|8xFZ{Ac+O@NeEMq%eiwm4}&)
zQAq!FUkeymA)H6Qe5@8Qus}JVB7hub5NGpieK7@o
s-mMI*Ob!g(*_;Y&S6R9?3j{=S!yGh2gcIyokb^fiDlu&~Dmupt0C*cU>;M1&
diff --git a/docker-compose.yml b/docker-compose.yml
index 40e2c449e..95ccac15d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -67,10 +67,7 @@ services:
abp-vue-admin-client:
build:
- context: ./vueJs
- volumes:
- - /var/opt/abp/data/client/nginx:/etc/nginx/nginx.conf
- - /var/opt/abp/data/client/nginx/conf.d:/etc/nginx/conf.d/default.conf
+ context: ./aspnet-core/services/Publish/client
restart: always
volumes:
diff --git a/vueJs/src/api/auditing.ts b/vueJs/src/api/auditing.ts
index 5cd00a57d..5b5590718 100644
--- a/vueJs/src/api/auditing.ts
+++ b/vueJs/src/api/auditing.ts
@@ -9,7 +9,7 @@ export default class AuditingService {
const _url = '/api/auditing/audit-log/' + id
return ApiService.Get(_url, serviceUrl)
}
-
+
public static getAuditLogs(payload: AuditLogGetPaged) {
let _url = '/api/auditing/audit-log?'
payload.skipCount = abpPagerFormat(payload.skipCount, payload.maxResultCount)
diff --git a/vueJs/src/views/admin/auditing/audit-log/index.vue b/vueJs/src/views/admin/auditing/audit-log/index.vue
index 242977f92..c9f39dfc4 100644
--- a/vueJs/src/views/admin/auditing/audit-log/index.vue
+++ b/vueJs/src/views/admin/auditing/audit-log/index.vue
@@ -125,7 +125,7 @@