diff --git a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs
index f3ecab99..55cc4893 100644
--- a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs
+++ b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs
@@ -1,5 +1,6 @@
using BaseOUDAL;
using Newtonsoft.Json;
+using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using YLErp.BLL;
@@ -540,23 +541,44 @@ namespace YLErp.Modules.RiskEngine
}
///
- /// 校验规则 ID 列表是否全部 Active
+ /// 校验规则状态可用性并确保编译缓存就绪。
+ /// 返回不可用规则信息列表,列表为空表示全部通过。
+ /// 规则不可用的情况:已删除、已停用、编译缓存缺失且刷新失败。
///
- private void ValidateRuleIdsActive(string ruleIds)
+ private List ValidateAndEnsureRuleCache(string ruleIds)
{
+ var errors = new List();
var ids = ParseRuleIds(ruleIds);
var rules = DbContext.glms_risk_rule
.Where(r => ids.Contains(r.id) && r.Status != RiskRuleStatus.Deleted)
.ToList();
if (rules.Count != ids.Count)
- throw new ServiceException("部分关联规则不存在或已删除");
+ {
+ var missingIds = ids.Except(rules.Select(r => (long)r.id)).ToList();
+ foreach (var id in missingIds)
+ errors.Add($"规则ID {id} 不存在或已删除");
+ return errors;
+ }
foreach (var rule in rules)
{
if (rule.Status == RiskRuleStatus.Disabled)
- throw new ServiceException($"关联规则 '{rule.RuleName}' 已停用,无法创建/启用应用配置");
+ {
+ errors.Add($"规则 '{rule.RuleName}' 已停用");
+ continue;
+ }
+
+ // 检查编译缓存,未命中则刷新
+ if (!RuleCompiledCache.TryGet(rule.id.ToString(), out _))
+ {
+ var result = RiskEngineService.GetInstance().RefreshOneRuleCache(rule.id);
+ if (!result.Success)
+ errors.Add($"规则 '{rule.RuleName}' 编译失败:{result.ErrorMessage}");
+ }
}
+
+ return errors;
}
///
@@ -1148,7 +1170,9 @@ namespace YLErp.Modules.RiskEngine
///
public RiskApplicationDetail CreateApplication(CreateRiskApplicationReq req)
{
- ValidateRuleIdsActive(req.RuleIds);
+ var errors = ValidateAndEnsureRuleCache(req.RuleIds);
+ if (errors.Any())
+ throw new ServiceException($"以下关联规则不可用:{string.Join(";", errors)}");
ValidateTriggerPoints(req.TriggerPoints);
ValidateScopeFields(req);
@@ -1209,7 +1233,11 @@ namespace YLErp.Modules.RiskEngine
throw new ServiceException("应用配置已被其他用户修改,请重新加载后再编辑");
if (!string.IsNullOrWhiteSpace(req.RuleIds))
- ValidateRuleIdsActive(req.RuleIds);
+ {
+ var errors = ValidateAndEnsureRuleCache(req.RuleIds);
+ if (errors.Any())
+ throw new ServiceException($"以下关联规则不可用:{string.Join(";", errors)}");
+ }
ValidateTriggerPoints(req.TriggerPoints);
var scopeReq = new CreateRiskApplicationReq
@@ -1274,7 +1302,9 @@ namespace YLErp.Modules.RiskEngine
if (app == null)
throw new ServiceException("仅已停用的应用配置可以启用");
- ValidateRuleIdsActive(app.RuleIds);
+ var errors = ValidateAndEnsureRuleCache(app.RuleIds);
+ if (errors.Any())
+ throw new ServiceException($"以下关联规则不可用:{string.Join(";", errors)}");
app.Status = RiskRuleStatus.Active;
app.UpdateOptId = UserId;
@@ -1319,9 +1349,23 @@ namespace YLErp.Modules.RiskEngine
if (apps.Count != applicationIds.Count)
throw new ServiceException("部分应用配置不存在或当前状态不允许启用");
+ var allErrors = new List();
foreach (var app in apps)
{
- ValidateRuleIdsActive(app.RuleIds);
+ var errors = ValidateAndEnsureRuleCache(app.RuleIds);
+ if (errors.Any())
+ allErrors.Add($"应用 '{app.Description}':{string.Join(";", errors)}");
+ }
+
+ if (allErrors.Any())
+ {
+ return new BatchOperationResult
+ {
+ Success = false,
+ TotalCount = applicationIds.Count,
+ SuccessCount = 0,
+ ErrorMessage = string.Join(";", allErrors)
+ };
}
foreach (var app in apps)