using Qdp.Foundation.Utilities;
using System.Threading.Tasks;
using YLErp.DBModels;
using YLErp.Modules.RiskEngine;
using YLErp.Modules.RiskEngine.Dto;
namespace YLErp.Web.Controllers
{
/// 风控引擎管理控制器,提供规则、应用配置、变量池和审计日志的 CRUD 接口
[Route("risk-engine")]
public class RiskRuleController : BaseController
{
private readonly IYcLogger _logger = LogFactory.GetLogger("RiskRuleController");
private RiskRuleService GetRiskRuleService() => new RiskRuleService(CurUser);
///
/// 格式化批量请求上下文,限制 ID 数量以避免异常日志过长。
///
private static string FormatBatchRequestContext(BatchIdsReq req)
{
var ids = req?.Ids?.Distinct().ToList() ?? new List();
var displayedIds = string.Join(",", ids.Take(20));
var truncated = ids.Count > 20 ? ",...(已截断)" : string.Empty;
return $"Count={ids.Count}, Ids={displayedIds}{truncated}";
}
#region Rule Management
[HttpGet("risk-rules")]
[MyAuthorize("风险控制-风控规则查看")]
/// 查询风控规则列表(分页)
public async Task QueryRiskRules(QueryRiskRuleReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.QueryRuleList(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询风控规则列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-rules/{id}")]
[MyAuthorize("风险控制-风控规则查看")]
/// 获取风控规则详情
public async Task GetRiskRule(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetRuleDetail(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询风控规则详情");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-rules/{id}/versions")]
[MyAuthorize("风险控制-风控规则查看")]
/// 获取风控规则版本历史
public async Task GetRiskRuleVersions(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetRuleVersions(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询风控规则版本历史");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-rules")]
[MyAuthorize("风险控制-风控规则新增")]
/// 创建风控规则
public async Task CreateRiskRule([FromBody] CreateRiskRuleReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.CreateRule(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "创建风控规则");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPut("risk-rules/{id}")]
[MyAuthorize("风险控制-风控规则编辑")]
/// 更新风控规则
public async Task UpdateRiskRule(long id, [FromBody] UpdateRiskRuleReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.UpdateRule(id, req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "更新风控规则");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-rules/{id}")]
[MyAuthorize("风险控制-风控规则删除")]
/// 删除风控规则(软删除)
public async Task DeleteRiskRule(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.DeleteRule(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "删除风控规则");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-rules/batch")]
[MyAuthorize("风险控制-风控规则删除")]
/// 批量删除风控规则
public async Task BatchDeleteRiskRules([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchDeleteRules(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量删除风控规则异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-rules/{id}/enable")]
[MyAuthorize("风险控制-风控规则启停")]
/// 启用风控规则
public async Task EnableRiskRule(long id)
{
try
{
var service = GetRiskRuleService();
await Task.Run(() => service.EnableRule(id));
return Json(new { success = true });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "启用风控规则");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-rules/{id}/disable")]
[MyAuthorize("风险控制-风控规则启停")]
/// 停用风控规则
public async Task DisableRiskRule(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.DisableRule(id));
return Json(new
{
success = true,
affectedActiveAppCount = result.AffectedActiveAppCount
});
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "停用风控规则");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-rules/batch-enable")]
[MyAuthorize("风险控制-风控规则启停")]
/// 批量启用风控规则
public async Task BatchEnableRiskRules([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchEnableRules(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量启用风控规则异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-rules/batch-disable")]
[MyAuthorize("风险控制-风控规则启停")]
/// 批量停用风控规则
public async Task BatchDisableRiskRules([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchDisableRules(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量停用风控规则异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-rules/{id}/applications")]
[MyAuthorize("风险控制-风控规则查看")]
/// 获取规则关联的应用配置列表
public async Task GetRuleApplications(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetRuleApplications(id));
return Json(new { success = true, data = new { rows = result, total = result.Count, records = result.Count, page = 1 } });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询规则关联应用列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-rules/list")]
[MyAuthorize("风险控制-风控规则查看")]
/// 获取所有未删除规则列表(供下拉选择)
public async Task GetAllRiskRules()
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetAllRuleList());
return Json(new { success = true, data = new { rows = result, total = result.Count, records = result.Count, page = 1 } });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询规则下拉列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
#endregion
#region Application Management
[HttpGet("risk-applications")]
[MyAuthorize("风险控制-风控应用查看")]
/// 查询应用配置列表(分页)
public async Task QueryRiskApplications(QueryRiskApplicationReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.QueryApplicationList(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询应用配置列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-applications/{id}")]
[MyAuthorize("风险控制-风控应用查看")]
/// 获取应用配置详情
public async Task GetRiskApplication(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetApplicationDetail(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询应用配置详情");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-applications")]
[MyAuthorize("风险控制-风控应用新增")]
/// 创建应用配置
public async Task CreateRiskApplication([FromBody] CreateRiskApplicationReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.CreateApplication(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "创建应用配置");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPut("risk-applications/{id}")]
[MyAuthorize("风险控制-风控应用编辑")]
/// 更新应用配置
public async Task UpdateRiskApplication(long id, [FromBody] UpdateRiskApplicationReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.UpdateApplication(id, req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "更新应用配置");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-applications/{id}")]
[MyAuthorize("风险控制-风控应用删除")]
/// 删除应用配置(软删除)
public async Task DeleteRiskApplication(long id)
{
try
{
var service = GetRiskRuleService();
await Task.Run(() => service.DeleteApplication(id));
return Json(new { success = true });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "删除应用配置");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-applications/{id}/enable")]
[MyAuthorize("风险控制-风控应用启停")]
/// 启用应用配置
public async Task EnableRiskApplication(long id)
{
try
{
var service = GetRiskRuleService();
await Task.Run(() => service.EnableApplication(id));
return Json(new { success = true });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "启用应用配置");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-applications/{id}/disable")]
[MyAuthorize("风险控制-风控应用启停")]
/// 停用应用配置
public async Task DisableRiskApplication(long id)
{
try
{
var service = GetRiskRuleService();
await Task.Run(() => service.DisableApplication(id));
return Json(new { success = true });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "停用应用配置");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-applications/batch-enable")]
[MyAuthorize("风险控制-风控应用启停")]
/// 批量启用应用配置
public async Task BatchEnableRiskApplications([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchEnableApplications(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量启用应用配置异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-applications/batch-disable")]
[MyAuthorize("风险控制-风控应用启停")]
/// 批量停用应用配置
public async Task BatchDisableRiskApplications([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchDisableApplications(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量停用应用配置异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-applications/batch")]
[MyAuthorize("风险控制-风控应用删除")]
/// 批量删除应用配置
public async Task BatchDeleteRiskApplications([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchDeleteApplications(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量删除应用配置异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
#endregion
#region Variable Management
[HttpGet("risk-variables")]
[MyAuthorize("风险控制-风控变量查看")]
/// 查询变量列表
public async Task QueryRiskVariables(QueryRiskVariableReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.QueryVariableList(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询变量列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-variables/{id}")]
[MyAuthorize("风险控制-风控变量查看")]
/// 获取变量详情
public async Task GetRiskVariable(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetVariableDetail(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询变量详情");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-variables/list")]
[MyAuthorize("风险控制-风控变量查看")]
/// 获取所有变量列表(供下拉选择)
public async Task GetAllRiskVariables()
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetAllVariableList());
return Json(new { success = true, data = new { rows = result, total = result.Count, records = result.Count, page = 1 } });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询全部变量列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPost("risk-variables")]
[MyAuthorize("风险控制-风控变量新增")]
/// 创建变量
public async Task CreateRiskVariable([FromBody] CreateRiskVariableReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.CreateVariable(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "创建变量");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpPut("risk-variables/{id}")]
[MyAuthorize("风险控制-风控变量编辑")]
/// 更新变量(含级联更新引用规则的 RuleExpr)
public async Task UpdateRiskVariable(long id, [FromBody] UpdateRiskVariableReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.UpdateVariable(id, req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "更新变量");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-variables/{id}")]
[MyAuthorize("风险控制-风控变量删除")]
/// 删除变量(软删除)
public async Task DeleteRiskVariable(long id)
{
try
{
var service = GetRiskRuleService();
await Task.Run(() => service.DeleteVariable(id));
return Json(new { success = true });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "删除变量");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpDelete("risk-variables/batch")]
[MyAuthorize("风险控制-风控变量删除")]
/// 批量删除变量(软删除)
public async Task BatchDeleteRiskVariables([FromBody] BatchIdsReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.BatchDeleteVariables(req?.Ids));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, $"批量删除变量异常,{FormatBatchRequestContext(req)}");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
#endregion
#region Trade Types
[HttpGet("trade-types")]
[MyAuthorize("风险控制-风控应用查看")]
/// 获取合约类型列表(纯内存操作,无需异步)
public JsonResult GetTradeTypes()
{
try
{
var rows = ConsTrade.AllTradeTypes.Select(t => new { label = t, value = t }).ToList();
var total = rows.Count;
return Json(new {
success = true,
data = new {
page = 1,
records = total,
rows = rows,
total = total
}
});
}
catch (Exception ex)
{
_logger.Error(ex, "查询合约类型列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
#endregion
#region Audit Log
[HttpGet("risk-audit-logs")]
[MyAuthorize("风险控制-风控日志查看")]
/// 查询风控操作日志列表(分页)
public async Task QueryRiskAuditLogs(QueryRiskAuditLogReq req)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.QueryAuditLogs(req));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询风控操作日志列表");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-audit-logs/{id}")]
[MyAuthorize("风险控制-风控日志查看")]
/// 获取风控操作日志详情
public async Task GetRiskAuditLogDetail(long id)
{
try
{
var service = GetRiskRuleService();
var result = await Task.Run(() => service.GetAuditLogDetail(id));
return Json(new { success = true, data = result });
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "查询风控操作日志详情");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
[HttpGet("risk-audit-logs/export")]
[MyAuthorize("风险控制-风控日志导出")]
/// 导出风控操作日志为 Excel
public async Task ExportRiskAuditLogs(QueryRiskAuditLogReq req)
{
try
{
var service = GetRiskRuleService();
var bytes = await Task.Run(() => service.ExportAuditLogs(req));
var fileName = service.BuildAuditLogExportFileName(req);
var encodedFileName = Uri.EscapeDataString(fileName);
Response.Headers["Content-Disposition"] = $"attachment; filename*=UTF-8''{encodedFileName}";
return File(bytes, xlsxMimeType);
}
catch (ServiceException ex)
{
return Json(new { success = false, message = ex.Message });
}
catch (Exception ex)
{
_logger.Error(ex, "导出风控操作日志");
return Json(new { success = false, message = "系统异常,请联系管理员" });
}
}
#endregion
}
}