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 } }