feat:优化风控引擎运行时,变量表的读取

This commit is contained in:
ruisu
2026-08-05 17:19:50 +08:00
parent f0ed2058bf
commit cfd5efd3d3
@@ -393,6 +393,35 @@ namespace YLErp.Modules.RiskEngine
_logger.Info($"[风控引擎] 匹配 TriggerPoint 的应用数: {matchedApplications.Count}");
// 汇总本次实际命中应用关联的结构化规则,变量定义只在本次检查开始时批量查询一次。
// 同一规则可能被多个应用引用,先对规则 ID 去重,避免重复处理规则定义。
var matchedRuleIds = matchedApplications
.SelectMany(application => ParseRuleIds(application.RuleIds))
.Distinct();
// 只保留当前规则缓存中存在的规则,配置中无效或已删除的规则 ID 仍由后续原有流程记录日志并跳过。
var matchedRules = matchedRuleIds
.Where(ruleMap.ContainsKey)
.Select(ruleId => ruleMap[ruleId]);
// 自由文本规则不依赖变量定义;条件缓存为空的结构化规则继续在执行阶段按原逻辑报错。
var structuredRules = matchedRules
.Where(rule => rule.Status == RiskRuleStatus.Active)
.Where(rule => !string.IsNullOrWhiteSpace(rule.ConditionJson))
.Where(rule => rule.ParsedConditions != null && rule.ParsedConditions.Count > 0);
// 条件中的主变量和变量阈值都需要加载,多条规则引用同一变量时只保留一个 ID。
var requiredVariableIds = structuredRules
.SelectMany(rule => RuleConditionExpressionBuilder.GetReferencedVariableIds(rule.ParsedConditions))
.Distinct()
.ToList();
if (requiredVariableIds.Any())
{
// 仅加载本次检查需要的变量,避免按规则逐次查询,也避免读取整个变量池。
variables = ruleDbContext.glms_risk_variable
.AsNoTracking()
.Where(variable => requiredVariableIds.Contains(variable.id))
.ToDictionary(variable => (long)variable.id);
}
// ============================================================
// Step 3: 遍历匹配的应用,通过 RuleIds 关联规则并执行预编译委托
// ============================================================
@@ -444,19 +473,6 @@ namespace YLErp.Modules.RiskEngine
throw new InvalidOperationException("结构化规则条件缓存为空");
var referencedVariableIds = RuleConditionExpressionBuilder.GetReferencedVariableIds(conditions);
var missingVariableIds = referencedVariableIds
.Where(id => !variables.ContainsKey(id))
.ToList();
if (missingVariableIds.Any())
{
// 按本次结构化规则实际引用的变量懒加载,避免每次风控检查全量读取变量池。
var loadedVariables = ruleDbContext.glms_risk_variable
.AsNoTracking()
.Where(v => missingVariableIds.Contains(v.id))
.ToDictionary(v => v.id);
foreach (var variable in loadedVariables)
variables[variable.Key] = variable.Value;
}
var ruleVariables = referencedVariableIds
.Where(variables.ContainsKey)