From c1ded96985dae45221045022f5e3538ed3245e4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=B9=E5=B3=B0?= Date: Thu, 9 Jul 2026 17:52:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=98=E9=87=8F=E7=BA=A7=E8=81=94=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E8=A7=84=E5=88=99=E4=BC=98=E5=8C=96&=E5=A2=9E?= =?UTF-8?q?=E8=A1=A5=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../YLErp.Core/DBModels/glms_risk_rule.cs | 12 ++ .../DBModels/glms_risk_rule_application.cs | 16 ++ .../DBModels/glms_risk_rule_audit_log.cs | 13 ++ .../YLErp.Core/DBModels/glms_risk_variable.cs | 15 ++ .../RiskEngine/Dto/BatchOperationResult.cs | 7 + .../Dto/CreateRiskApplicationReq.cs | 11 + .../RiskEngine/Dto/CreateRiskRuleReq.cs | 7 + .../RiskEngine/Dto/CreateRiskVariableReq.cs | 11 + .../RiskEngine/Dto/QueryRiskApplicationReq.cs | 11 + .../RiskEngine/Dto/QueryRiskAuditLogReq.cs | 11 + .../RiskEngine/Dto/QueryRiskRuleReq.cs | 6 + .../RiskEngine/Dto/QueryRiskVariableReq.cs | 6 + .../RiskEngine/Dto/RiskApplicationDetail.cs | 18 ++ .../RiskEngine/Dto/RiskApplicationListItem.cs | 18 ++ .../RiskEngine/Dto/RiskAuditLogDetail.cs | 14 ++ .../RiskEngine/Dto/RiskAuditLogListItem.cs | 12 ++ .../Dto/RiskRuleApplicationSummary.cs | 7 + .../Modules/RiskEngine/Dto/RiskRuleDetail.cs | 15 ++ .../RiskEngine/Dto/RiskRuleListItem.cs | 15 ++ .../RiskEngine/Dto/RiskRuleSimpleItem.cs | 6 + .../RiskEngine/Dto/RiskRuleVersionItem.cs | 8 + .../RiskEngine/Dto/RiskVariableDetail.cs | 18 ++ .../RiskEngine/Dto/RiskVariableListItem.cs | 13 ++ .../RiskEngine/Dto/RiskVariableSimpleItem.cs | 9 + .../Modules/RiskEngine/Dto/RuleCondition.cs | 11 +- .../Dto/UpdateRiskApplicationReq.cs | 12 ++ .../RiskEngine/Dto/UpdateRiskRuleReq.cs | 8 + .../RiskEngine/Dto/UpdateRiskVariableReq.cs | 12 ++ .../Modules/RiskEngine/RiskRuleService.cs | 194 +++++++++++++++++- YLErpWeb/Controllers/RiskRuleController.cs | 32 +++ 30 files changed, 545 insertions(+), 3 deletions(-) diff --git a/Framework/YLErp.Core/DBModels/glms_risk_rule.cs b/Framework/YLErp.Core/DBModels/glms_risk_rule.cs index 1581b02f..ad756d55 100644 --- a/Framework/YLErp.Core/DBModels/glms_risk_rule.cs +++ b/Framework/YLErp.Core/DBModels/glms_risk_rule.cs @@ -2,17 +2,29 @@ using System.ComponentModel.DataAnnotations.Schema; namespace YLErp.DBModels { + /// + /// 风控规则定义表 + /// [Table("glms_risk_rule")] public class glms_risk_rule : DBModelWithOperator { + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } + /// 结构化条件 JSON(变量+操作符+阈值列表) public string ConditionJson { get; set; } + /// 规则执行表达式(C# 布尔表达式,引擎用 Roslyn 编译执行) public string RuleExpr { get; set; } + /// 规则状态 public RiskRuleStatus Status { get; set; } = RiskRuleStatus.Active; + /// 版本号(乐观锁) public int Version { get; set; } = 1; + /// 最后更新人工号 public int? UpdateOptId { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime? UpdateDate { get; set; } } } diff --git a/Framework/YLErp.Core/DBModels/glms_risk_rule_application.cs b/Framework/YLErp.Core/DBModels/glms_risk_rule_application.cs index a1d577ac..f6cefd70 100644 --- a/Framework/YLErp.Core/DBModels/glms_risk_rule_application.cs +++ b/Framework/YLErp.Core/DBModels/glms_risk_rule_application.cs @@ -2,21 +2,37 @@ using System.ComponentModel.DataAnnotations.Schema; namespace YLErp.DBModels { + /// + /// 风控规则应用配置表 + /// [Table("glms_risk_rule_application")] public class glms_risk_rule_application : DBModelWithOperator { + /// 关联规则 ID 列表(JSON 数组) public string RuleIds { get; set; } + /// 应用配置状态 public RiskRuleStatus Status { get; set; } = RiskRuleStatus.Active; + /// 风控策略(预警/阻断) public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表(JSON 数组) public string TriggerPoints { get; set; } + /// 适用范围-资产账簿 ID 列表(JSON 数组) public string ScopeAssetBookIds { get; set; } + /// 适用范围-客户 ID 列表(JSON 数组) public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表(JSON 数组) public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表(JSON 数组) public string ScopeTradeTypes { get; set; } + /// 是否全局生效(0:否 1:是) public int ScopeIsGlobal { get; set; } + /// 版本号(乐观锁) public int Version { get; set; } = 1; + /// 最后更新人工号 public int? UpdateOptId { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime? UpdateDate { get; set; } } } diff --git a/Framework/YLErp.Core/DBModels/glms_risk_rule_audit_log.cs b/Framework/YLErp.Core/DBModels/glms_risk_rule_audit_log.cs index fca43e2b..0ffdd3fe 100644 --- a/Framework/YLErp.Core/DBModels/glms_risk_rule_audit_log.cs +++ b/Framework/YLErp.Core/DBModels/glms_risk_rule_audit_log.cs @@ -2,18 +2,31 @@ using System.ComponentModel.DataAnnotations.Schema; namespace YLErp.DBModels { + /// + /// 风控操作审计日志表 + /// [Table("glms_risk_rule_audit_log")] public class glms_risk_rule_audit_log : DBModelBase { + /// 操作类型(创建/更新/删除/启用/禁用) public string OperationType { get; set; } + /// 操作目标类型(Rule/Variable/Application) public string TargetType { get; set; } + /// 操作目标 ID public long TargetId { get; set; } + /// 操作目标名称 public string TargetName { get; set; } + /// 操作详情描述 public string OperationDetail { get; set; } + /// 操作结果(成功/失败) public string Result { get; set; } + /// 操作前数据快照(JSON) public string SnapshotData { get; set; } + /// 操作人工号 public long OptId { get; set; } + /// 操作人姓名 public string OptName { get; set; } + /// 操作时间 public DateTime OptDate { get; set; } } } diff --git a/Framework/YLErp.Core/DBModels/glms_risk_variable.cs b/Framework/YLErp.Core/DBModels/glms_risk_variable.cs index 099312ae..2a856819 100644 --- a/Framework/YLErp.Core/DBModels/glms_risk_variable.cs +++ b/Framework/YLErp.Core/DBModels/glms_risk_variable.cs @@ -2,20 +2,35 @@ using System.ComponentModel.DataAnnotations.Schema; namespace YLErp.DBModels { + /// + /// 风控变量池定义表 + /// [Table("glms_risk_variable")] public class glms_risk_variable : DBModelWithOperator { + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 值域描述 public string ValueDomain { get; set; } + /// 变量说明 public string Description { get; set; } + /// 取值表达式(C# 表达式,用于计算变量值) public string VariableExpr { get; set; } + /// 版本号(乐观锁) public int Version { get; set; } = 1; + /// 排序序号 public int SortOrder { get; set; } + /// 最后更新人工号 public int? UpdateOptId { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime? UpdateDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/BatchOperationResult.cs b/YLErpDAL/Modules/RiskEngine/Dto/BatchOperationResult.cs index 0aed2a39..7d9dccb1 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/BatchOperationResult.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/BatchOperationResult.cs @@ -1,10 +1,17 @@ namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 批量操作结果 + /// public class BatchOperationResult { + /// 是否全部成功 public bool Success { get; set; } + /// 总数量 public int TotalCount { get; set; } + /// 成功数量 public int SuccessCount { get; set; } + /// 错误信息 public string ErrorMessage { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskApplicationReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskApplicationReq.cs index 65e939c4..71914328 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskApplicationReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskApplicationReq.cs @@ -2,15 +2,26 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 创建应用配置请求 + /// public class CreateRiskApplicationReq { + /// 关联规则 ID 列表(JSON 数组) public string RuleIds { get; set; } + /// 风控策略 public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表(JSON 数组) public string TriggerPoints { get; set; } + /// 适用范围-资产账簿 ID 列表 public string ScopeAssetBookIds { get; set; } + /// 适用范围-客户 ID 列表 public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表 public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表 public string ScopeTradeTypes { get; set; } + /// 是否全局生效 public int ScopeIsGlobal { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskRuleReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskRuleReq.cs index a6d69dda..df27186d 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskRuleReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskRuleReq.cs @@ -1,10 +1,17 @@ namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 创建风控规则请求 + /// public class CreateRiskRuleReq { + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } + /// 结构化条件 JSON public string ConditionJson { get; set; } + /// 规则执行表达式 public string RuleExpr { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskVariableReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskVariableReq.cs index 707db27b..e8bff83a 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskVariableReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/CreateRiskVariableReq.cs @@ -2,15 +2,26 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 创建变量请求 + /// public class CreateRiskVariableReq { + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 值域描述 public string ValueDomain { get; set; } + /// 变量说明 public string Description { get; set; } + /// 取值表达式 public string VariableExpr { get; set; } + /// 排序序号 public int SortOrder { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs index eec45ca7..0a501867 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs @@ -3,15 +3,26 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 查询应用配置请求 + /// public class QueryRiskApplicationReq : BaseSearchReq { + /// 规则名称 public string RuleName { get; set; } + /// 应用配置状态 public RiskRuleStatus? Status { get; set; } + /// 风控策略 public RiskControlStrategy? Strategy { get; set; } + /// 触发点 public string TriggerPoint { get; set; } + /// 适用范围-客户 ID 列表 public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表 public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表 public string ScopeTradeTypes { get; set; } + /// 适用范围-资产账簿 ID 列表 public string ScopeAssetBookIds { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskAuditLogReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskAuditLogReq.cs index 6e77c983..d1f9d242 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskAuditLogReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskAuditLogReq.cs @@ -3,15 +3,26 @@ using BaseOUDAL; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 查询审计日志请求 + /// public class QueryRiskAuditLogReq : BaseSearchReq { + /// 操作类型 public string OperationType { get; set; } + /// 操作类型列表(多选,逗号分隔) public string OperationTypes { get; set; } + /// 操作目标类型 public string TargetType { get; set; } + /// 操作目标名称 public string TargetName { get; set; } + /// 操作人姓名 public string OptName { get; set; } + /// 开始日期 public DateTime? StartDate { get; set; } + /// 结束日期 public DateTime? EndDate { get; set; } + /// 搜索关键词 public string Keyword { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskRuleReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskRuleReq.cs index df7e1300..8339b900 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskRuleReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskRuleReq.cs @@ -3,10 +3,16 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 查询风控规则请求 + /// public class QueryRiskRuleReq : BaseSearchReq { + /// 搜索关键词 public string Keyword { get; set; } + /// 规则状态 public RiskRuleStatus? Status { get; set; } + /// 关联变量 ID public long? VariableId { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs index 9b8f39bd..ed4b9901 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs @@ -3,10 +3,16 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 查询变量请求 + /// public class QueryRiskVariableReq : BaseSearchReq { + /// 变量分类 public RiskVariableCategory? Category { get; set; } + /// 数据类型 public RiskVariableDataType? DataType { get; set; } + /// 变量名称 public string VariableName { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationDetail.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationDetail.cs index cb76b20c..648a08b8 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationDetail.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationDetail.cs @@ -3,22 +3,40 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 应用配置详情响应 + /// public class RiskApplicationDetail { + /// 应用配置 ID public long Id { get; set; } + /// 关联规则 ID 列表(JSON 数组) public string RuleIds { get; set; } + /// 应用配置状态 public RiskRuleStatus Status { get; set; } + /// 风控策略 public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表(JSON 数组) public string TriggerPoints { get; set; } + /// 适用范围-资产账簿 ID 列表 public string ScopeAssetBookIds { get; set; } + /// 适用范围-客户 ID 列表 public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表 public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表 public string ScopeTradeTypes { get; set; } + /// 是否全局生效 public int ScopeIsGlobal { get; set; } + /// 版本号 public int Version { get; set; } + /// 创建人姓名 public string OptName { get; set; } + /// 创建时间 public DateTime OptDate { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime UpdateDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationListItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationListItem.cs index 466b1d94..fec34ea9 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationListItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskApplicationListItem.cs @@ -3,22 +3,40 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 应用配置列表项 + /// public class RiskApplicationListItem { + /// 应用配置 ID public long Id { get; set; } + /// 关联规则 ID 列表(JSON 数组) public string RuleIds { get; set; } + /// 应用配置状态 public int Status { get; set; } + /// 风控策略 public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表(JSON 数组) public string TriggerPoints { get; set; } + /// 适用范围-资产账簿 ID 列表 public string ScopeAssetBookIds { get; set; } + /// 适用范围-客户 ID 列表 public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表 public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表 public string ScopeTradeTypes { get; set; } + /// 是否全局生效 public int ScopeIsGlobal { get; set; } + /// 版本号 public int Version { get; set; } + /// 创建人姓名 public string OptName { get; set; } + /// 创建时间 public DateTime OptDate { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime UpdateDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogDetail.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogDetail.cs index a4f52acf..e9418ec4 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogDetail.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogDetail.cs @@ -2,18 +2,32 @@ using System; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 审计日志详情响应 + /// public class RiskAuditLogDetail { + /// 日志 ID public long Id { get; set; } + /// 操作类型 public string OperationType { get; set; } + /// 操作目标类型 public string TargetType { get; set; } + /// 操作目标 ID public long TargetId { get; set; } + /// 操作目标名称 public string TargetName { get; set; } + /// 操作详情描述 public string OperationDetail { get; set; } + /// 操作结果 public string Result { get; set; } + /// 操作前数据快照(JSON) public string SnapshotData { get; set; } + /// 操作人工号 public long OptId { get; set; } + /// 操作人姓名 public string OptName { get; set; } + /// 操作时间 public DateTime OptDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogListItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogListItem.cs index 487f5f3f..3e2288ab 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogListItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskAuditLogListItem.cs @@ -2,16 +2,28 @@ using System; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 审计日志列表项 + /// public class RiskAuditLogListItem { + /// 日志 ID public long Id { get; set; } + /// 操作类型 public string OperationType { get; set; } + /// 操作目标类型 public string TargetType { get; set; } + /// 操作目标 ID public long TargetId { get; set; } + /// 操作目标名称 public string TargetName { get; set; } + /// 操作详情描述 public string OperationDetail { get; set; } + /// 操作结果 public string Result { get; set; } + /// 操作人姓名 public string OptName { get; set; } + /// 操作时间 public DateTime OptDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleApplicationSummary.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleApplicationSummary.cs index 23c6e0e2..da6b37e4 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleApplicationSummary.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleApplicationSummary.cs @@ -2,11 +2,18 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 规则关联应用摘要 + /// public class RiskRuleApplicationSummary { + /// 应用配置 ID public long Id { get; set; } + /// 应用配置状态 public RiskRuleStatus Status { get; set; } + /// 风控策略 public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表 public string TriggerPoints { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleDetail.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleDetail.cs index 6abe752d..09364933 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleDetail.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleDetail.cs @@ -4,19 +4,34 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 风控规则详情响应 + /// public class RiskRuleDetail { + /// 规则 ID public long Id { get; set; } + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } + /// 结构化条件 JSON public string ConditionJson { get; set; } + /// 规则执行表达式 public string RuleExpr { get; set; } + /// 规则状态 public RiskRuleStatus Status { get; set; } + /// 版本号 public int Version { get; set; } + /// 创建人姓名 public string OptName { get; set; } + /// 创建时间 public DateTime OptDate { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime UpdateDate { get; set; } + /// 关联应用列表 public List Applications { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs index 988f55c4..32a462e2 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs @@ -3,19 +3,34 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 风控规则列表项 + /// public class RiskRuleListItem { + /// 规则 ID public long Id { get; set; } + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } + /// 结构化条件 JSON public string ConditionJson { get; set; } + /// 规则执行表达式 public string RuleExpr { get; set; } + /// 规则状态 public RiskRuleStatus Status { get; set; } + /// 版本号 public int Version { get; set; } + /// 创建人姓名 public string OptName { get; set; } + /// 创建时间 public DateTime OptDate { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime UpdateDate { get; set; } + /// 关联应用数量 public int ApplicationCount { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleSimpleItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleSimpleItem.cs index aea6a343..d2d98568 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleSimpleItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleSimpleItem.cs @@ -1,9 +1,15 @@ namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 风控规则简要信息 + /// public class RiskRuleSimpleItem { + /// 规则 ID public long Id { get; set; } + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleVersionItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleVersionItem.cs index b0842d6e..0e15cd14 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleVersionItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleVersionItem.cs @@ -2,12 +2,20 @@ using System; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 风控规则版本历史项 + /// public class RiskRuleVersionItem { + /// 版本号 public int Version { get; set; } + /// 操作类型 public string OperationType { get; set; } + /// 操作详情 public string OperationDetail { get; set; } + /// 操作人姓名 public string OptName { get; set; } + /// 操作时间 public DateTime OptDate { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableDetail.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableDetail.cs index bbadd4ce..c3dee5a8 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableDetail.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableDetail.cs @@ -3,22 +3,40 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 变量详情响应 + /// public class RiskVariableDetail { + /// 变量 ID public long Id { get; set; } + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 值域描述 public string ValueDomain { get; set; } + /// 变量说明 public string Description { get; set; } + /// 取值表达式 public string VariableExpr { get; set; } + /// 版本号 public int Version { get; set; } + /// 排序序号 public int SortOrder { get; set; } + /// 创建人姓名 public string OptName { get; set; } + /// 创建时间 public DateTime OptDate { get; set; } + /// 最后更新人姓名 public string UpdateOptName { get; set; } + /// 最后更新时间 public DateTime UpdateDate { get; set; } + /// 被引用次数 public int ReferenceCount { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableListItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableListItem.cs index c4ddf647..538cdcb9 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableListItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableListItem.cs @@ -2,17 +2,30 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 变量列表项 + /// public class RiskVariableListItem { + /// 变量 ID public long Id { get; set; } + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 值域描述 public string ValueDomain { get; set; } + /// 变量说明 public string Description { get; set; } + /// 取值表达式 public string VariableExpr { get; set; } + /// 版本号 public int Version { get; set; } + /// 排序序号 public int SortOrder { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableSimpleItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableSimpleItem.cs index 8585564d..f884a03e 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableSimpleItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskVariableSimpleItem.cs @@ -2,13 +2,22 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 变量简要信息 + /// public class RiskVariableSimpleItem { + /// 变量 ID public long Id { get; set; } + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 取值表达式 public string VariableExpr { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RuleCondition.cs b/YLErpDAL/Modules/RiskEngine/Dto/RuleCondition.cs index d1e459ff..071be483 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RuleCondition.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RuleCondition.cs @@ -1,14 +1,23 @@ namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 规则条件项 + /// public class RuleCondition { + /// 条件变量 ID public long VariableId { get; set; } + /// 操作符(如 Equal、GreaterThan、Between 等) public string Operator { get; set; } + /// 阈值类型(FixedValue / VariableRef) public string ThresholdType { get; set; } + /// 阈值(固定值或变量引用) public object Value { get; set; } + /// 阈值变量 ID(当 ThresholdType 为 VariableRef 时) public long? ThresholdVariableId { get; set; } - // 介于/不介于 的边界包含控制,默认 true + /// 介于/不介于的下边界是否包含,默认 true public bool IncludeLowerBound { get; set; } = true; + /// 介于/不介于的上边界是否包含,默认 true public bool IncludeUpperBound { get; set; } = true; } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs index aa290529..f152f276 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs @@ -2,16 +2,28 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 更新应用配置请求 + /// public class UpdateRiskApplicationReq { + /// 关联规则 ID 列表(JSON 数组) public string RuleIds { get; set; } + /// 风控策略 public RiskControlStrategy ControlStrategy { get; set; } + /// 触发点列表(JSON 数组) public string TriggerPoints { get; set; } + /// 适用范围-资产账簿 ID 列表 public string ScopeAssetBookIds { get; set; } + /// 适用范围-客户 ID 列表 public string ScopeClientIds { get; set; } + /// 适用范围-标的类型列表 public string ScopeUnderlyingTypes { get; set; } + /// 适用范围-交易类型列表 public string ScopeTradeTypes { get; set; } + /// 是否全局生效 public int ScopeIsGlobal { get; set; } + /// 版本号(乐观锁) public int Version { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs index 85521bac..9fa13d3c 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs @@ -1,11 +1,19 @@ namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 更新风控规则请求 + /// public class UpdateRiskRuleReq { + /// 规则名称 public string RuleName { get; set; } + /// 规则描述文本 public string RuleText { get; set; } + /// 结构化条件 JSON public string ConditionJson { get; set; } + /// 规则执行表达式 public string RuleExpr { get; set; } + /// 版本号(乐观锁) public int Version { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs index 2990b7c1..c9ca1b3a 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs @@ -2,16 +2,28 @@ using YLErp.DBModels; namespace YLErp.Modules.RiskEngine.Dto { + /// + /// 更新变量请求 + /// public class UpdateRiskVariableReq { + /// 变量名称 public string VariableName { get; set; } + /// 变量分类 public RiskVariableCategory Category { get; set; } + /// 数据类型 public RiskVariableDataType DataType { get; set; } + /// 单位 public string Unit { get; set; } + /// 值域描述 public string ValueDomain { get; set; } + /// 变量说明 public string Description { get; set; } + /// 取值表达式 public string VariableExpr { get; set; } + /// 排序序号 public int SortOrder { get; set; } + /// 版本号(乐观锁) public int Version { get; set; } } } diff --git a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs index 08421a07..b2162888 100644 --- a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs +++ b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs @@ -221,6 +221,9 @@ namespace YLErp.Modules.RiskEngine #region Private Helpers + /// + /// 写入审计日志 + /// private void WriteAuditLog(string operationType, string targetType, long targetId, string targetName, string operationDetail, string result = "成功", string snapshotData = null) { @@ -240,6 +243,9 @@ namespace YLErp.Modules.RiskEngine DbContext.glms_risk_rule_audit_log.Add(log); } + /// + /// 获取变量表达式集合(5 分钟本地缓存) + /// private HashSet GetVariableExprSet() { if (_variableExprCache == null || @@ -254,11 +260,17 @@ namespace YLErp.Modules.RiskEngine return _variableExprCache; } + /// + /// 失效变量表达式缓存 + /// private void InvalidateVariableCache() { _variableExprCache = null; } + /// + /// 校验 ConditionJson(结构化模式:变量存在性、操作符、类型匹配) + /// private void ValidateConditionJson(string conditionJson) { List conditions; @@ -341,6 +353,9 @@ namespace YLErp.Modules.RiskEngine } } + /// + /// 校验 RuleExpr(自由文本模式:括号匹配) + /// private void ValidateRuleExpr(string ruleExpr) { if (ruleExpr.Length > 10000) @@ -358,6 +373,9 @@ namespace YLErp.Modules.RiskEngine throw new ServiceException("公式表达式括号不匹配:缺少右括号"); } + /// + /// 校验触发时点 + /// private void ValidateTriggerPoints(string triggerPoints) { if (string.IsNullOrWhiteSpace(triggerPoints)) @@ -375,6 +393,9 @@ namespace YLErp.Modules.RiskEngine throw new ServiceException("至少需要指定一个触发时点"); } + /// + /// 校验 Scope 适用范围字段 + /// private void ValidateScopeFields(CreateRiskApplicationReq req) { if (req.ScopeIsGlobal == 1) @@ -400,6 +421,9 @@ namespace YLErp.Modules.RiskEngine } } + /// + /// 校验 ID 列表格式 + /// private void ValidateIdList(string idList, string fieldName) { var parts = idList.Split(','); @@ -410,6 +434,9 @@ namespace YLErp.Modules.RiskEngine } } + /// + /// 尝试刷新引擎缓存(不抛异常) + /// private void TryRefreshCache() { try @@ -422,6 +449,9 @@ namespace YLErp.Modules.RiskEngine } } + /// + /// 获取数据类型中文名 + /// private string GetDataTypeName(RiskVariableDataType dataType) { return dataType switch @@ -433,6 +463,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 获取规则实体,不存在则抛异常 + /// private glms_risk_rule GetRuleOrThrow(long ruleId) { var rule = DbContext.glms_risk_rule.FirstOrDefault(r => r.id == ruleId && r.Status != RiskRuleStatus.Deleted); @@ -441,6 +474,9 @@ namespace YLErp.Modules.RiskEngine return rule; } + /// + /// 获取应用配置实体,不存在则抛异常 + /// private glms_risk_rule_application GetApplicationOrThrow(long applicationId) { var app = DbContext.glms_risk_rule_application.FirstOrDefault(a => a.id == applicationId && a.Status != RiskRuleStatus.Deleted); @@ -449,6 +485,9 @@ namespace YLErp.Modules.RiskEngine return app; } + /// + /// 获取变量实体,不存在则抛异常 + /// private glms_risk_variable GetVariableOrThrow(long variableId) { var variable = DbContext.glms_risk_variable.FirstOrDefault(v => v.id == variableId); @@ -457,6 +496,9 @@ namespace YLErp.Modules.RiskEngine return variable; } + /// + /// 校验规则参数(名称 + ConditionJson + RuleExpr) + /// private void ValidateRuleParams(string ruleName, string conditionJson, string ruleExpr) { if (string.IsNullOrWhiteSpace(ruleName)) @@ -475,6 +517,9 @@ namespace YLErp.Modules.RiskEngine ValidateRuleExpr(ruleExpr); } + /// + /// 解析逗号分隔的规则 ID 字符串为 List + /// private List ParseRuleIds(string ruleIds) { if (string.IsNullOrWhiteSpace(ruleIds)) @@ -495,6 +540,9 @@ namespace YLErp.Modules.RiskEngine return ids; } + /// + /// 校验规则 ID 列表是否全部 Active + /// private void ValidateRuleIdsActive(string ruleIds) { var ids = ParseRuleIds(ruleIds); @@ -512,6 +560,9 @@ namespace YLErp.Modules.RiskEngine } } + /// + /// 根据规则 ID 字符串解析为规则名称字符串 + /// private string ResolveRuleNames(string ruleIds) { if (string.IsNullOrWhiteSpace(ruleIds)) @@ -569,6 +620,9 @@ namespace YLErp.Modules.RiskEngine return predicate != null ? query.Where(predicate) : query; } + /// + /// 获取控制策略中文名 + /// private static string GetStrategyName(RiskControlStrategy strategy) { return strategy switch @@ -589,6 +643,9 @@ namespace YLErp.Modules.RiskEngine ["FUND_PAYMENT"] = "资金支付" }; + /// + /// 将触发时点映射为中文 + /// private static string MapTriggerPointsToChinese(string triggerPoints) { if (string.IsNullOrWhiteSpace(triggerPoints)) @@ -603,6 +660,9 @@ namespace YLErp.Modules.RiskEngine #region Rule Management + /// + /// 查询规则列表(分页,含 ApplicationCount 子查询) + /// public SearchListResult QueryRuleList(QueryRiskRuleReq req) { var query = DbContext.glms_risk_rule @@ -646,6 +706,9 @@ namespace YLErp.Modules.RiskEngine return result.ToSearchList(req); } + /// + /// 获取规则详情(含关联应用摘要) + /// public RiskRuleDetail GetRuleDetail(long ruleId) { var rule = GetRuleOrThrow(ruleId); @@ -679,6 +742,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 创建规则(ConditionJson 完整校验,事务包裹) + /// public RiskRuleDetail CreateRule(CreateRiskRuleReq req) { ValidateRuleParams(req.RuleName, req.ConditionJson, req.RuleExpr); @@ -723,6 +789,9 @@ namespace YLErp.Modules.RiskEngine return GetRuleDetail(entity.id); } + /// + /// 更新规则(乐观锁校验,Version+1) + /// public RiskRuleDetail UpdateRule(long ruleId, UpdateRiskRuleReq req) { var rule = GetRuleOrThrow(ruleId); @@ -749,6 +818,9 @@ namespace YLErp.Modules.RiskEngine return GetRuleDetail(ruleId); } + /// + /// 删除规则(软删除,有 Active 应用引用时拒绝) + /// public void DeleteRule(long ruleId) { var rule = GetRuleOrThrow(ruleId); @@ -771,6 +843,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 启用规则(仅 Disabled → Active) + /// public void EnableRule(long ruleId) { var rule = DbContext.glms_risk_rule.FirstOrDefault(r => r.id == ruleId && r.Status == RiskRuleStatus.Disabled); @@ -788,6 +863,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 停用规则(仅 Active → Disabled) + /// public void DisableRule(long ruleId) { var rule = DbContext.glms_risk_rule.FirstOrDefault(r => r.id == ruleId && r.Status == RiskRuleStatus.Active); @@ -805,6 +883,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 获取规则版本历史(从审计日志 SnapshotData 提取) + /// public List GetRuleVersions(long ruleId) { GetRuleOrThrow(ruleId); @@ -842,6 +923,9 @@ namespace YLErp.Modules.RiskEngine return result; } + /// + /// 批量删除规则(逐条保护检查) + /// public BatchOperationResult BatchDeleteRules(List ruleIds) { var rules = DbContext.glms_risk_rule @@ -882,6 +966,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 获取规则关联的应用配置列表 + /// public List GetRuleApplications(long ruleId) { GetRuleOrThrow(ruleId); @@ -918,6 +1005,9 @@ namespace YLErp.Modules.RiskEngine return result; } + /// + /// 获取所有启用规则列表(轻量字段,供下拉选择) + /// public List GetAllRuleList() { return DbContext.glms_risk_rule @@ -936,6 +1026,9 @@ namespace YLErp.Modules.RiskEngine #region Application Management + /// + /// 查询应用配置列表(多条件筛选,内存关联规则名称) + /// public SearchListResult QueryApplicationList(QueryRiskApplicationReq req) { var query = DbContext.glms_risk_rule_application @@ -1000,6 +1093,9 @@ namespace YLErp.Modules.RiskEngine return pagedResult; } + /// + /// 获取应用配置详情(含关联规则信息) + /// public RiskApplicationDetail GetApplicationDetail(long applicationId) { var app = DbContext.glms_risk_rule_application @@ -1027,6 +1123,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 创建应用配置(关联规则 Active 校验,事务包裹) + /// public RiskApplicationDetail CreateApplication(CreateRiskApplicationReq req) { ValidateRuleIdsActive(req.RuleIds); @@ -1078,6 +1177,9 @@ namespace YLErp.Modules.RiskEngine return GetApplicationDetail(entity.id); } + /// + /// 更新应用配置(乐观锁校验) + /// public RiskApplicationDetail UpdateApplication(long applicationId, UpdateRiskApplicationReq req) { var app = GetApplicationOrThrow(applicationId); @@ -1122,6 +1224,9 @@ namespace YLErp.Modules.RiskEngine return GetApplicationDetail(applicationId); } + /// + /// 删除应用配置(软删除) + /// public void DeleteApplication(long applicationId) { var app = GetApplicationOrThrow(applicationId); @@ -1138,6 +1243,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 启用应用配置(校验关联规则状态) + /// public void EnableApplication(long applicationId) { var app = DbContext.glms_risk_rule_application.FirstOrDefault(a => a.id == applicationId && a.Status == RiskRuleStatus.Disabled); @@ -1157,6 +1265,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 停用应用配置 + /// public void DisableApplication(long applicationId) { var app = DbContext.glms_risk_rule_application.FirstOrDefault(a => a.id == applicationId && a.Status == RiskRuleStatus.Active); @@ -1174,6 +1285,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 批量启用应用配置(逐条校验关联规则) + /// public BatchOperationResult BatchEnableApplications(List applicationIds) { var apps = DbContext.glms_risk_rule_application @@ -1209,6 +1323,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 批量停用应用配置 + /// public BatchOperationResult BatchDisableApplications(List applicationIds) { var apps = DbContext.glms_risk_rule_application @@ -1243,6 +1360,9 @@ namespace YLErp.Modules.RiskEngine #region Variable Management + /// + /// 查询变量列表(全量返回,Category/Keyword 筛选) + /// public SearchListResult QueryVariableList(QueryRiskVariableReq req) { var query = DbContext.glms_risk_variable.AsQueryable(); @@ -1280,6 +1400,9 @@ namespace YLErp.Modules.RiskEngine return result.ToSearchList(req); } + /// + /// 获取变量详情(含 ReferenceCount 引用统计) + /// public RiskVariableDetail GetVariableDetail(long variableId) { var variable = GetVariableOrThrow(variableId); @@ -1310,6 +1433,9 @@ namespace YLErp.Modules.RiskEngine }; } + /// + /// 创建变量(VariableExpr 长度校验 ≤10000,事务包裹) + /// public RiskVariableDetail CreateVariable(CreateRiskVariableReq req) { if (string.IsNullOrWhiteSpace(req.VariableName)) @@ -1363,6 +1489,9 @@ namespace YLErp.Modules.RiskEngine return GetVariableDetail(entity.id); } + /// + /// 更新变量(乐观锁,DataType 变更保护,级联更新引用规则 RuleExpr) + /// public RiskVariableDetail UpdateVariable(long variableId, UpdateRiskVariableReq req) { var variable = GetVariableOrThrow(variableId); @@ -1386,6 +1515,8 @@ namespace YLErp.Modules.RiskEngine throw new ServiceException($"该变量被 {activeRefCount} 个生效中的规则引用,无法修改数据类型"); } + var oldVariableExpr = variable.VariableExpr; + variable.VariableName = req.VariableName; variable.Category = req.Category; variable.DataType = req.DataType; @@ -1399,8 +1530,52 @@ namespace YLErp.Modules.RiskEngine variable.UpdateOptName = UserName; variable.UpdateDate = DateTime.Now; - WriteAuditLog("VAR_UPDATE", "VARIABLE", variableId, req.VariableName, $"修改变量:{variable.VariableName}"); - DbContext.SaveChanges(); + var variableExprChanged = oldVariableExpr != req.VariableExpr; + + if (variableExprChanged) + { + using (var transaction = DbContext.Database.BeginTransaction()) + { + try + { + var affectedRules = DbContext.glms_risk_rule + .Where(r => r.RuleExpr != null && r.RuleExpr.Contains(oldVariableExpr)) + .ToList(); + + foreach (var rule in affectedRules) + { + rule.RuleExpr = rule.RuleExpr.Replace(oldVariableExpr, req.VariableExpr); + rule.Version = rule.Version + 1; + rule.UpdateOptId = UserId; + rule.UpdateOptName = UserName; + rule.UpdateDate = DateTime.Now; + } + + DbContext.SaveChanges(); + + WriteAuditLog("VAR_UPDATE", "VARIABLE", variableId, req.VariableName, $"修改变量:{variable.VariableName}"); + + foreach (var rule in affectedRules) + { + WriteAuditLog("VAR_UPDATE_CASCADE", "RULE", rule.id, rule.RuleName, + $"变量 [{variable.VariableName}] VariableExpr 变更,级联更新规则 RuleExpr"); + } + + DbContext.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + } + else + { + WriteAuditLog("VAR_UPDATE", "VARIABLE", variableId, req.VariableName, $"修改变量:{variable.VariableName}"); + DbContext.SaveChanges(); + } InvalidateVariableCache(); TryRefreshCache(); @@ -1408,6 +1583,9 @@ namespace YLErp.Modules.RiskEngine return GetVariableDetail(variableId); } + /// + /// 删除变量(有 Active 引用时拒绝) + /// public void DeleteVariable(long variableId) { var variable = GetVariableOrThrow(variableId); @@ -1429,6 +1607,9 @@ namespace YLErp.Modules.RiskEngine TryRefreshCache(); } + /// + /// 获取所有变量列表(供下拉选择) + /// public List GetAllVariableList() { var result = DbContext.glms_risk_variable @@ -1452,6 +1633,9 @@ namespace YLErp.Modules.RiskEngine #region Audit Log + /// + /// 查询审计日志列表(分页) + /// public SearchListResult QueryAuditLogs(QueryRiskAuditLogReq req) { var query = DbContext.glms_risk_rule_audit_log.AsQueryable(); @@ -1516,11 +1700,17 @@ namespace YLErp.Modules.RiskEngine return result.ToSearchList(req); } + /// + /// 导出审计日志为 Excel + /// public byte[] ExportAuditLogs(QueryRiskAuditLogReq req) { throw new ServiceException("导出功能暂未实现"); } + /// + /// 获取审计日志详情 + /// public RiskAuditLogDetail GetAuditLogDetail(long logId) { var log = DbContext.glms_risk_rule_audit_log.FirstOrDefault(l => l.id == logId); diff --git a/YLErpWeb/Controllers/RiskRuleController.cs b/YLErpWeb/Controllers/RiskRuleController.cs index c6f238a3..d45ac656 100644 --- a/YLErpWeb/Controllers/RiskRuleController.cs +++ b/YLErpWeb/Controllers/RiskRuleController.cs @@ -5,6 +5,7 @@ using YLErp.Modules.RiskEngine.Dto; namespace YLErp.Web.Controllers { + /// 风控引擎管理控制器,提供规则、应用配置、变量池和审计日志的 CRUD 接口 [Route("risk-engine")] public class RiskRuleController : BaseController { @@ -14,6 +15,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-rules")] [MyAuthorize("风险控制-风控规则查看")] + /// 查询风控规则列表(分页) public JsonResult QueryRiskRules(QueryRiskRuleReq req) { try @@ -35,6 +37,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-rules/{id}")] [MyAuthorize("风险控制-风控规则查看")] + /// 获取风控规则详情 public JsonResult GetRiskRule(long id) { try @@ -56,6 +59,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-rules/{id}/versions")] [MyAuthorize("风险控制-风控规则查看")] + /// 获取风控规则版本历史 public JsonResult GetRiskRuleVersions(long id) { try @@ -77,6 +81,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-rules")] [MyAuthorize("风险控制-风控规则新增")] + /// 创建风控规则 public JsonResult CreateRiskRule([FromBody] CreateRiskRuleReq req) { try @@ -98,6 +103,7 @@ namespace YLErp.Web.Controllers [HttpPut("risk-rules/{id}")] [MyAuthorize("风险控制-风控规则编辑")] + /// 更新风控规则 public JsonResult UpdateRiskRule(long id, [FromBody] UpdateRiskRuleReq req) { try @@ -119,6 +125,7 @@ namespace YLErp.Web.Controllers [HttpDelete("risk-rules/{id}")] [MyAuthorize("风险控制-风控规则删除")] + /// 删除风控规则(软删除) public JsonResult DeleteRiskRule(long id) { try @@ -140,6 +147,7 @@ namespace YLErp.Web.Controllers [HttpDelete("risk-rules/batch")] [MyAuthorize("风险控制-风控规则删除")] + /// 批量删除风控规则 public JsonResult BatchDeleteRiskRules([FromBody] List ids) { try @@ -161,6 +169,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-rules/{id}/enable")] [MyAuthorize("风险控制-风控规则启停")] + /// 启用风控规则 public JsonResult EnableRiskRule(long id) { try @@ -182,6 +191,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-rules/{id}/disable")] [MyAuthorize("风险控制-风控规则启停")] + /// 停用风控规则 public JsonResult DisableRiskRule(long id) { try @@ -203,6 +213,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-rules/{id}/applications")] [MyAuthorize("风险控制-风控规则查看")] + /// 获取规则关联的应用配置列表 public JsonResult GetRuleApplications(long id) { try @@ -224,6 +235,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-rules/list")] [MyAuthorize("风险控制-风控规则查看")] + /// 获取所有启用规则列表(供下拉选择) public JsonResult GetAllRiskRules() { try @@ -249,6 +261,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-applications")] [MyAuthorize("风险控制-风控应用查看")] + /// 查询应用配置列表(分页) public JsonResult QueryRiskApplications(QueryRiskApplicationReq req) { try @@ -270,6 +283,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-applications/{id}")] [MyAuthorize("风险控制-风控应用查看")] + /// 获取应用配置详情 public JsonResult GetRiskApplication(long id) { try @@ -291,6 +305,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-applications")] [MyAuthorize("风险控制-风控应用新增")] + /// 创建应用配置 public JsonResult CreateRiskApplication([FromBody] CreateRiskApplicationReq req) { try @@ -312,6 +327,7 @@ namespace YLErp.Web.Controllers [HttpPut("risk-applications/{id}")] [MyAuthorize("风险控制-风控应用编辑")] + /// 更新应用配置 public JsonResult UpdateRiskApplication(long id, [FromBody] UpdateRiskApplicationReq req) { try @@ -333,6 +349,7 @@ namespace YLErp.Web.Controllers [HttpDelete("risk-applications/{id}")] [MyAuthorize("风险控制-风控应用删除")] + /// 删除应用配置(软删除) public JsonResult DeleteRiskApplication(long id) { try @@ -354,6 +371,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-applications/{id}/enable")] [MyAuthorize("风险控制-风控应用启停")] + /// 启用应用配置 public JsonResult EnableRiskApplication(long id) { try @@ -375,6 +393,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-applications/{id}/disable")] [MyAuthorize("风险控制-风控应用启停")] + /// 停用应用配置 public JsonResult DisableRiskApplication(long id) { try @@ -396,6 +415,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-applications/batch-enable")] [MyAuthorize("风险控制-风控应用启停")] + /// 批量启用应用配置 public JsonResult BatchEnableRiskApplications([FromBody] List ids) { try @@ -417,6 +437,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-applications/batch-disable")] [MyAuthorize("风险控制-风控应用启停")] + /// 批量停用应用配置 public JsonResult BatchDisableRiskApplications([FromBody] List ids) { try @@ -442,6 +463,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-variables")] [MyAuthorize("风险控制-风控变量查看")] + /// 查询变量列表 public JsonResult QueryRiskVariables(QueryRiskVariableReq req) { try @@ -463,6 +485,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-variables/{id}")] [MyAuthorize("风险控制-风控变量查看")] + /// 获取变量详情 public JsonResult GetRiskVariable(long id) { try @@ -484,6 +507,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-variables/list")] [MyAuthorize("风险控制-风控变量查看")] + /// 获取所有变量列表(供下拉选择) public JsonResult GetAllRiskVariables() { try @@ -505,6 +529,7 @@ namespace YLErp.Web.Controllers [HttpPost("risk-variables")] [MyAuthorize("风险控制-风控变量新增")] + /// 创建变量 public JsonResult CreateRiskVariable([FromBody] CreateRiskVariableReq req) { try @@ -526,6 +551,7 @@ namespace YLErp.Web.Controllers [HttpPut("risk-variables/{id}")] [MyAuthorize("风险控制-风控变量编辑")] + /// 更新变量(含级联更新引用规则的 RuleExpr) public JsonResult UpdateRiskVariable(long id, [FromBody] UpdateRiskVariableReq req) { try @@ -547,6 +573,7 @@ namespace YLErp.Web.Controllers [HttpDelete("risk-variables/{id}")] [MyAuthorize("风险控制-风控变量删除")] + /// 删除变量 public JsonResult DeleteRiskVariable(long id) { try @@ -572,6 +599,7 @@ namespace YLErp.Web.Controllers [HttpGet("riskCache/refresh")] [MyAuthorize("风险控制-异常交易监控")] + /// 手动刷新风控引擎缓存 public JsonResult RefreshRiskEngineCache() { try @@ -596,6 +624,7 @@ namespace YLErp.Web.Controllers [HttpGet("trade-types")] [MyAuthorize("风险控制-风控应用查看")] + /// 获取合约类型列表 public JsonResult GetTradeTypes() { try @@ -625,6 +654,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-audit-logs")] [MyAuthorize("风险控制-风控日志查看")] + /// 查询风控操作日志列表(分页) public JsonResult QueryRiskAuditLogs(QueryRiskAuditLogReq req) { try @@ -646,6 +676,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-audit-logs/{id}")] [MyAuthorize("风险控制-风控日志查看")] + /// 获取风控操作日志详情 public JsonResult GetRiskAuditLogDetail(long id) { try @@ -667,6 +698,7 @@ namespace YLErp.Web.Controllers [HttpGet("risk-audit-logs/export")] [MyAuthorize("风险控制-风控日志导出")] + /// 导出风控操作日志为 Excel public IActionResult ExportRiskAuditLogs(QueryRiskAuditLogReq req) { try