bugfix:规则批量启用
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
/// <summary>
|
||||
/// 批量操作请求(兼容前端 {ids: [...]} 格式)
|
||||
/// </summary>
|
||||
public class BatchIdsReq
|
||||
{
|
||||
public List<long> Ids { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -540,6 +540,19 @@ namespace YLErp.Modules.RiskEngine
|
||||
return ids;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// EF Core 可翻译的逗号分隔字段精确匹配表达式
|
||||
/// </summary>
|
||||
private static Expression<Func<glms_risk_rule_application, bool>> RuleIdsMatchExpr(long ruleId)
|
||||
{
|
||||
var idStr = ruleId.ToString();
|
||||
return a => a.RuleIds != null &&
|
||||
(a.RuleIds == idStr ||
|
||||
a.RuleIds.StartsWith(idStr + ",") ||
|
||||
a.RuleIds.EndsWith("," + idStr) ||
|
||||
a.RuleIds.Contains("," + idStr + ","));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验规则状态可用性并确保编译缓存就绪。
|
||||
/// 返回不可用规则信息列表,列表为空表示全部通过。
|
||||
@@ -722,7 +735,12 @@ namespace YLErp.Modules.RiskEngine
|
||||
OptDate = r.OptDate.GetValueOrDefault(),
|
||||
UpdateOptName = r.UpdateOptName,
|
||||
UpdateDate = r.UpdateDate ?? r.OptDate.GetValueOrDefault(),
|
||||
ApplicationCount = DbContext.glms_risk_rule_application.Count(a => a.RuleIds.Contains(r.id.ToString()) && a.Status != RiskRuleStatus.Deleted)
|
||||
ApplicationCount = DbContext.glms_risk_rule_application
|
||||
.Count(a => a.RuleIds != null &&
|
||||
(a.RuleIds == r.id.ToString() ||
|
||||
a.RuleIds.StartsWith(r.id.ToString() + ",") ||
|
||||
a.RuleIds.EndsWith("," + r.id.ToString()) ||
|
||||
a.RuleIds.Contains("," + r.id.ToString() + ",")))
|
||||
});
|
||||
|
||||
return result.ToSearchList(req);
|
||||
@@ -735,9 +753,9 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
var rule = GetRuleOrThrow(ruleId);
|
||||
|
||||
var ruleIdStr = ruleId.ToString();
|
||||
|
||||
var applications = DbContext.glms_risk_rule_application
|
||||
.Where(a => a.RuleIds.Contains(ruleIdStr) && a.Status != RiskRuleStatus.Deleted)
|
||||
.Where(RuleIdsMatchExpr(ruleId))
|
||||
.Select(a => new RiskRuleApplicationSummary
|
||||
{
|
||||
Id = a.id,
|
||||
@@ -858,9 +876,10 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
var rule = GetRuleOrThrow(ruleId);
|
||||
|
||||
var ruleIdStr = ruleId.ToString();
|
||||
|
||||
var activeCount = DbContext.glms_risk_rule_application
|
||||
.Count(a => a.RuleIds.Contains(ruleIdStr) && a.Status == RiskRuleStatus.Active);
|
||||
.Where(a => a.Status == RiskRuleStatus.Active)
|
||||
.Count(RuleIdsMatchExpr(ruleId));
|
||||
if (activeCount > 0)
|
||||
throw new ServiceException($"该规则仍有 {activeCount} 个生效中的应用配置,请先停用或删除相关应用");
|
||||
|
||||
@@ -965,24 +984,58 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// </summary>
|
||||
public BatchOperationResult BatchDeleteRules(List<long> ruleIds)
|
||||
{
|
||||
if (ruleIds == null || ruleIds.Count == 0)
|
||||
throw new ServiceException("规则ID列表不能为空");
|
||||
|
||||
_logger.Info($"[批量删除] 开始 - 传入规则数: {ruleIds.Count}, IDs: {string.Join(",", ruleIds)}");
|
||||
|
||||
var rules = DbContext.glms_risk_rule
|
||||
.Where(r => ruleIds.Contains(r.id) && r.Status != RiskRuleStatus.Deleted)
|
||||
.ToList();
|
||||
|
||||
if (rules.Count != ruleIds.Count)
|
||||
throw new ServiceException("部分规则不存在或已删除");
|
||||
_logger.Info($"[批量删除] DB查询完成 - 匹配到 {rules.Count} 条规则");
|
||||
|
||||
var foundIds = rules.Select(r => (long)r.id).ToList();
|
||||
var missingIds = ruleIds.Except(foundIds).ToList();
|
||||
if (missingIds.Any())
|
||||
{
|
||||
return new BatchOperationResult
|
||||
{
|
||||
Success = false,
|
||||
TotalCount = ruleIds.Count,
|
||||
SuccessCount = 0,
|
||||
ErrorMessage = $"以下规则不存在或已删除:{string.Join(", ", missingIds)}"
|
||||
};
|
||||
}
|
||||
|
||||
var blockedRules = new List<string>();
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
var ruleIdStr = rule.id.ToString();
|
||||
var activeCount = DbContext.glms_risk_rule_application
|
||||
.Count(a => a.RuleIds.Contains(ruleIdStr) && a.Status == RiskRuleStatus.Active);
|
||||
_logger.Info($"[批量删除] 检查关联应用 - 规则ID: {rule.id}");
|
||||
var activeApps = DbContext.glms_risk_rule_application
|
||||
.Where(a => a.Status == RiskRuleStatus.Active)
|
||||
.Where(RuleIdsMatchExpr(rule.id))
|
||||
.Select(a => (long)a.id)
|
||||
.ToList();
|
||||
var activeCount = activeApps.Count;
|
||||
_logger.Info($"[批量删除] 关联应用检查结果 - 规则ID: {rule.id}, ActiveCount: {activeCount}, AppIds: [{string.Join(",", activeApps)}]");
|
||||
if (activeCount > 0)
|
||||
throw new ServiceException($"规则 '{rule.RuleName}' 仍有 {activeCount} 个生效中的应用配置,请先停用或删除相关应用");
|
||||
blockedRules.Add($"规则 '{rule.RuleName}'(ID:{rule.id}) 仍有 {activeCount} 个生效中的应用配置(IDs: {string.Join(",", activeApps)})");
|
||||
}
|
||||
if (blockedRules.Any())
|
||||
{
|
||||
return new BatchOperationResult
|
||||
{
|
||||
Success = false,
|
||||
TotalCount = ruleIds.Count,
|
||||
SuccessCount = 0,
|
||||
ErrorMessage = string.Join(";", blockedRules)
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var rule in rules)
|
||||
{
|
||||
_logger.Info($"[批量删除] 写入状态 - 规则ID: {rule.id}");
|
||||
rule.Status = RiskRuleStatus.Deleted;
|
||||
rule.Version = rule.Version + 1;
|
||||
rule.UpdateOptId = UserId;
|
||||
@@ -992,11 +1045,14 @@ namespace YLErp.Modules.RiskEngine
|
||||
WriteAuditLog("RULE_BATCH_DELETE", "RULE", rule.id, rule.RuleName, "批量删除规则");
|
||||
}
|
||||
|
||||
_logger.Info("[批量删除] 保存数据库...");
|
||||
DbContext.SaveChanges();
|
||||
_logger.Info("[批量删除] 刷新规则缓存...");
|
||||
foreach (var ruleId in ruleIds)
|
||||
{
|
||||
RiskEngineService.GetInstance().RefreshOneRuleCache(ruleId);
|
||||
}
|
||||
_logger.Info("[批量删除] 完成");
|
||||
|
||||
return new BatchOperationResult
|
||||
{
|
||||
@@ -1013,9 +1069,8 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
GetRuleOrThrow(ruleId);
|
||||
|
||||
var ruleIdStr = ruleId.ToString();
|
||||
var apps = DbContext.glms_risk_rule_application
|
||||
.Where(a => a.RuleIds.Contains(ruleIdStr) && a.Status != RiskRuleStatus.Deleted)
|
||||
.Where(RuleIdsMatchExpr(ruleId))
|
||||
.OrderByDescending(a => a.UpdateDate)
|
||||
.ToList();
|
||||
|
||||
@@ -1093,8 +1148,12 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
query = query.Where(a => DbContext.glms_risk_rule
|
||||
.Any(r => r.Status != RiskRuleStatus.Deleted
|
||||
&& a.RuleIds.Contains(r.id.ToString())
|
||||
&& r.RuleName.Contains(req.RuleName)));
|
||||
&& r.RuleName.Contains(req.RuleName)
|
||||
&& a.RuleIds != null
|
||||
&& (a.RuleIds == r.id.ToString()
|
||||
|| a.RuleIds.StartsWith(r.id.ToString() + ",")
|
||||
|| a.RuleIds.EndsWith("," + r.id.ToString())
|
||||
|| a.RuleIds.Contains("," + r.id.ToString() + ","))));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.ScopeClientIds))
|
||||
@@ -1342,16 +1401,46 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// </summary>
|
||||
public BatchOperationResult BatchEnableApplications(List<long> applicationIds)
|
||||
{
|
||||
_logger.Info($"[批量启用] 开始 - 传入应用数: {applicationIds?.Count ?? 0}, IDs: {string.Join(",", applicationIds ?? new List<long>())}");
|
||||
if (applicationIds == null || applicationIds.Count == 0)
|
||||
throw new ServiceException("应用配置ID列表不能为空");
|
||||
|
||||
_logger.Info($"[批量启用] 开始 - 传入应用数: {applicationIds.Count}, IDs: {string.Join(",", applicationIds)}");
|
||||
|
||||
var apps = DbContext.glms_risk_rule_application
|
||||
.Where(a => applicationIds.Contains(a.id) && a.Status == RiskRuleStatus.Disabled)
|
||||
.Where(a => applicationIds.Contains(a.id))
|
||||
.ToList();
|
||||
|
||||
_logger.Info($"[批量启用] DB查询完成 - 匹配到 {apps.Count} 条已停用应用");
|
||||
_logger.Info($"[批量启用] DB查询完成 - 匹配到 {apps.Count} 条应用");
|
||||
|
||||
if (apps.Count != applicationIds.Count)
|
||||
throw new ServiceException("部分应用配置不存在或当前状态不允许启用");
|
||||
var foundIds = apps.Select(a => (long)a.id).ToList();
|
||||
var missingIds = applicationIds.Except(foundIds).ToList();
|
||||
if (missingIds.Any())
|
||||
{
|
||||
return new BatchOperationResult
|
||||
{
|
||||
Success = false,
|
||||
TotalCount = applicationIds.Count,
|
||||
SuccessCount = 0,
|
||||
ErrorMessage = $"以下应用配置不存在:{string.Join(", ", missingIds)}"
|
||||
};
|
||||
}
|
||||
|
||||
// 跳过已启用的应用,只处理已停用的
|
||||
var skippedIds = apps.Where(a => a.Status == RiskRuleStatus.Active).Select(a => (long)a.id).ToList();
|
||||
if (skippedIds.Any())
|
||||
_logger.Info($"[批量启用] 跳过已启用应用 - IDs: {string.Join(",", skippedIds)}");
|
||||
|
||||
apps = apps.Where(a => a.Status != RiskRuleStatus.Active).ToList();
|
||||
if (!apps.Any())
|
||||
{
|
||||
_logger.Info("[批量启用] 所有应用均已启用,无需操作");
|
||||
return new BatchOperationResult
|
||||
{
|
||||
Success = true,
|
||||
TotalCount = applicationIds.Count,
|
||||
SuccessCount = applicationIds.Count
|
||||
};
|
||||
}
|
||||
|
||||
var allErrors = new List<string>();
|
||||
foreach (var app in apps)
|
||||
@@ -1404,7 +1493,10 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// </summary>
|
||||
public BatchOperationResult BatchDisableApplications(List<long> applicationIds)
|
||||
{
|
||||
_logger.Info($"[批量停用] 开始 - 传入应用数: {applicationIds?.Count ?? 0}, IDs: {string.Join(",", applicationIds ?? new List<long>())}");
|
||||
if (applicationIds == null || applicationIds.Count == 0)
|
||||
throw new ServiceException("应用配置ID列表不能为空");
|
||||
|
||||
_logger.Info($"[批量停用] 开始 - 传入应用数: {applicationIds.Count}, IDs: {string.Join(",", applicationIds)}");
|
||||
|
||||
var apps = DbContext.glms_risk_rule_application
|
||||
.Where(a => applicationIds.Contains(a.id) && a.Status == RiskRuleStatus.Active)
|
||||
@@ -1412,8 +1504,18 @@ namespace YLErp.Modules.RiskEngine
|
||||
|
||||
_logger.Info($"[批量停用] DB查询完成 - 匹配到 {apps.Count} 条已启用应用");
|
||||
|
||||
if (apps.Count != applicationIds.Count)
|
||||
throw new ServiceException("部分应用配置不存在或当前状态不允许停用");
|
||||
var foundIds = apps.Select(a => (long)a.id).ToList();
|
||||
var missingIds = applicationIds.Except(foundIds).ToList();
|
||||
if (missingIds.Any())
|
||||
{
|
||||
return new BatchOperationResult
|
||||
{
|
||||
Success = false,
|
||||
TotalCount = applicationIds.Count,
|
||||
SuccessCount = apps.Count,
|
||||
ErrorMessage = $"以下应用配置不存在或当前状态不允许停用:{string.Join(", ", missingIds)}"
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var app in apps)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Qdp.Foundation.Utilities;
|
||||
using Qdp.Foundation.Utilities;
|
||||
using System.Threading.Tasks;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Modules.RiskEngine;
|
||||
@@ -151,12 +151,14 @@ namespace YLErp.Web.Controllers
|
||||
[HttpDelete("risk-rules/batch")]
|
||||
[MyAuthorize("风险控制-风控规则删除")]
|
||||
/// <summary>批量删除风控规则</summary>
|
||||
public async Task<JsonResult> BatchDeleteRiskRules([FromBody] List<long> ids)
|
||||
public async Task<JsonResult> BatchDeleteRiskRules([FromBody] BatchIdsReq req)
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = GetRiskRuleService();
|
||||
var result = await Task.Run(() => service.BatchDeleteRules(ids));
|
||||
var result = await Task.Run(() => service.BatchDeleteRules(req?.Ids));
|
||||
if (!result.Success)
|
||||
return Json(new { success = false, message = result.ErrorMessage });
|
||||
return Json(new { success = true, data = result });
|
||||
}
|
||||
catch (ServiceException ex)
|
||||
@@ -419,12 +421,14 @@ namespace YLErp.Web.Controllers
|
||||
[HttpPost("risk-applications/batch-enable")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
/// <summary>批量启用应用配置</summary>
|
||||
public async Task<JsonResult> BatchEnableRiskApplications([FromBody] List<long> ids)
|
||||
public async Task<JsonResult> BatchEnableRiskApplications([FromBody] BatchIdsReq req)
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = GetRiskRuleService();
|
||||
var result = await Task.Run(() => service.BatchEnableApplications(ids));
|
||||
var result = await Task.Run(() => service.BatchEnableApplications(req?.Ids));
|
||||
if (!result.Success)
|
||||
return Json(new { success = false, message = result.ErrorMessage });
|
||||
return Json(new { success = true, data = result });
|
||||
}
|
||||
catch (ServiceException ex)
|
||||
@@ -441,12 +445,14 @@ namespace YLErp.Web.Controllers
|
||||
[HttpPost("risk-applications/batch-disable")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
/// <summary>批量停用应用配置</summary>
|
||||
public async Task<JsonResult> BatchDisableRiskApplications([FromBody] List<long> ids)
|
||||
public async Task<JsonResult> BatchDisableRiskApplications([FromBody] BatchIdsReq req)
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = GetRiskRuleService();
|
||||
var result = await Task.Run(() => service.BatchDisableApplications(ids));
|
||||
var result = await Task.Run(() => service.BatchDisableApplications(req?.Ids));
|
||||
if (!result.Success)
|
||||
return Json(new { success = false, message = result.ErrorMessage });
|
||||
return Json(new { success = true, data = result });
|
||||
}
|
||||
catch (ServiceException ex)
|
||||
|
||||
Reference in New Issue
Block a user