Merge branch 'feature/p132_74-risk-engine' of https://gitee.glmszq.com/gsty/onederiv/trs into feature/p132_74-risk-engine
This commit is contained in:
@@ -13,7 +13,7 @@ namespace YLErp.DBModels
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
public int Version { get; set; } = 1;
|
||||
public int? UpdateOptId { get; set; }
|
||||
public string UpdateOptName { get; set; }
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
-- ============================================================
|
||||
-- 异常交易监控页面 - 操作权限(按钮)数据
|
||||
-- 依赖:异常交易监控菜单 id=1077 (type=1) 需先插入
|
||||
-- 对应 FunctionRight.xml 风险控制下风控相关操作权限(共16个按钮)
|
||||
-- type: 0=目录 1=菜单 2=按钮
|
||||
-- ============================================================
|
||||
|
||||
-- ----------------------------
|
||||
-- 1. sys_menu 页面+按钮(type=1,2)
|
||||
-- ----------------------------
|
||||
INSERT INTO `yltrs_admin`.`sys_menu` (`id`, `pid`, `pids`, `name`, `code`, `type`, `icon`, `router`, `component`, `permission`, `application`, `open_type`, `visible`, `link`, `redirect`, `weight`, `sort`, `remark`, `status`, `create_time`, `create_user`, `update_time`, `update_user`) VALUES
|
||||
(1077, 99, NULL, '异常交易监控', NULL, 1, NULL, NULL, NULL, '异常交易监控', NULL, NULL, NULL, NULL, NULL, NULL, 0, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1078, 1077, NULL, '风控规则查看', NULL, 2, NULL, NULL, NULL, '风控规则查看', NULL, NULL, NULL, NULL, NULL, NULL, 1, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1079, 1077, NULL, '风控规则新增', NULL, 2, NULL, NULL, NULL, '风控规则新增', NULL, NULL, NULL, NULL, NULL, NULL, 2, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1080, 1077, NULL, '风控规则编辑', NULL, 2, NULL, NULL, NULL, '风控规则编辑', NULL, NULL, NULL, NULL, NULL, NULL, 3, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1081, 1077, NULL, '风控规则删除', NULL, 2, NULL, NULL, NULL, '风控规则删除', NULL, NULL, NULL, NULL, NULL, NULL, 4, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1082, 1077, NULL, '风控规则启停', NULL, 2, NULL, NULL, NULL, '风控规则启停', NULL, NULL, NULL, NULL, NULL, NULL, 5, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1083, 1077, NULL, '风控应用查看', NULL, 2, NULL, NULL, NULL, '风控应用查看', NULL, NULL, NULL, NULL, NULL, NULL, 6, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1084, 1077, NULL, '风控应用新增', NULL, 2, NULL, NULL, NULL, '风控应用新增', NULL, NULL, NULL, NULL, NULL, NULL, 7, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1085, 1077, NULL, '风控应用编辑', NULL, 2, NULL, NULL, NULL, '风控应用编辑', NULL, NULL, NULL, NULL, NULL, NULL, 8, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1086, 1077, NULL, '风控应用删除', NULL, 2, NULL, NULL, NULL, '风控应用删除', NULL, NULL, NULL, NULL, NULL, NULL, 9, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1087, 1077, NULL, '风控应用启停', NULL, 2, NULL, NULL, NULL, '风控应用启停', NULL, NULL, NULL, NULL, NULL, NULL, 10, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1088, 1077, NULL, '风控变量查看', NULL, 2, NULL, NULL, NULL, '风控变量查看', NULL, NULL, NULL, NULL, NULL, NULL, 11, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1089, 1077, NULL, '风控变量新增', NULL, 2, NULL, NULL, NULL, '风控变量新增', NULL, NULL, NULL, NULL, NULL, NULL, 12, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1090, 1077, NULL, '风控变量编辑', NULL, 2, NULL, NULL, NULL, '风控变量编辑', NULL, NULL, NULL, NULL, NULL, NULL, 13, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1091, 1077, NULL, '风控变量删除', NULL, 2, NULL, NULL, NULL, '风控变量删除', NULL, NULL, NULL, NULL, NULL, NULL, 14, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1092, 1077, NULL, '风控日志查看', NULL, 2, NULL, NULL, NULL, '风控日志查看', NULL, NULL, NULL, NULL, NULL, NULL, 15, '', 0, NULL, NULL, NULL, NULL),
|
||||
(1093, 1077, NULL, '风控日志导出', NULL, 2, NULL, NULL, NULL, '风控日志导出', NULL, NULL, NULL, NULL, NULL, NULL, 16, '', 0, NULL, NULL, NULL, NULL);
|
||||
|
||||
-- ----------------------------
|
||||
-- 2. sys_role_menu 角色1的按钮权限
|
||||
-- ----------------------------
|
||||
INSERT INTO `yltrs_admin`.`sys_role_menu` (`id`, `role_id`, `menu_id`) VALUES
|
||||
(1097, 1, 1077),
|
||||
(1098, 1, 1078),
|
||||
(1099, 1, 1079),
|
||||
(1100, 1, 1080),
|
||||
(1101, 1, 1081),
|
||||
(1102, 1, 1082),
|
||||
(1103, 1, 1083),
|
||||
(1104, 1, 1084),
|
||||
(1105, 1, 1085),
|
||||
(1106, 1, 1086),
|
||||
(1107, 1, 1087),
|
||||
(1108, 1, 1088),
|
||||
(1109, 1, 1089),
|
||||
(1110, 1, 1090),
|
||||
(1111, 1, 1091),
|
||||
(1112, 1, 1092),
|
||||
(1113, 1, 1093);
|
||||
@@ -50,7 +50,7 @@ INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr
|
||||
'挂钩标的到期日早于合约到期日时禁止交易',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 22,
|
||||
'Operator', '<', 'ThresholdType', 'Variable',
|
||||
'Operator', '早于', 'ThresholdType', 'Variable',
|
||||
'ThresholdVariableId', 3
|
||||
)),
|
||||
'market.UnderlyingMaturityDate < trade.ExerciseDate',
|
||||
@@ -87,7 +87,8 @@ INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr
|
||||
'保证金利率不在配置区间内(默认2%~5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 12,
|
||||
'Operator', '不介于', 'ThresholdType', 'Fixed', 'Value', JSON_ARRAY(2, 5)
|
||||
'Operator', '不介于', 'ThresholdType', 'Fixed', 'Value', JSON_ARRAY(2, 5),
|
||||
'IncludeLowerBound', true, 'IncludeUpperBound', true
|
||||
)),
|
||||
'!(client_marginrate.InitMarginRebateRate >= 2 && client_marginrate.InitMarginRebateRate <= 5)',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
@@ -112,7 +113,7 @@ INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr
|
||||
'合约起息日早于当前日期时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 2,
|
||||
'Operator', '<', 'ThresholdType', 'Variable',
|
||||
'Operator', '早于', 'ThresholdType', 'Variable',
|
||||
'ThresholdVariableId', 21
|
||||
)),
|
||||
'trade.StartDate < sys.CurrentDate',
|
||||
|
||||
@@ -189,6 +189,29 @@ namespace YLErp.Modules.RiskEngine
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将操作符统一为 C# 操作符
|
||||
/// </summary>
|
||||
private static string FormatOperator(string op)
|
||||
{
|
||||
return op?.Trim() switch
|
||||
{
|
||||
// 数值型 C# 符号
|
||||
"=" or "==" => "==",
|
||||
"!=" or "≠" => "!=",
|
||||
">" => ">",
|
||||
"<" => "<",
|
||||
">=" => ">=",
|
||||
"<=" => "<=",
|
||||
// 日期型中文语义 → C# 符号
|
||||
"早于" => "<",
|
||||
"晚于" => ">",
|
||||
"等于" => "==",
|
||||
"不早于" => ">=",
|
||||
"不晚于" => "<=",
|
||||
_ => throw new ArgumentException($"不支持的操作符:{op}")
|
||||
};
|
||||
}
|
||||
public static BuildMemberAccessResult Fail(string errorMessage)
|
||||
{
|
||||
return new BuildMemberAccessResult
|
||||
|
||||
@@ -11,6 +11,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,9 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public RiskRuleStatus? Status { get; set; }
|
||||
public RiskControlStrategy? Strategy { get; set; }
|
||||
public string TriggerPoint { get; set; }
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public string ScopeAssetBookIds { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class QueryRiskAuditLogReq : BaseSearchReq
|
||||
{
|
||||
public string OperationType { get; set; }
|
||||
public string OperationTypes { get; set; }
|
||||
public string TargetType { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
public string OptName { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public DateTime? EndDate { get; set; }
|
||||
public string Keyword { get; set; }
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class QueryRiskVariableReq : BaseSearchReq
|
||||
{
|
||||
public RiskVariableCategory? Category { get; set; }
|
||||
public RiskVariableDataType? DataType { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
public int Version { get; set; }
|
||||
public string OptName { get; set; }
|
||||
public DateTime OptDate { get; set; }
|
||||
|
||||
@@ -7,14 +7,14 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string RuleIds { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public int Status { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
public string ScopeAssetBookIds { get; set; }
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
public int Version { get; set; }
|
||||
public string OptName { get; set; }
|
||||
public DateTime OptDate { get; set; }
|
||||
|
||||
@@ -7,5 +7,8 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string ThresholdType { get; set; }
|
||||
public object Value { get; set; }
|
||||
public long? ThresholdVariableId { get; set; }
|
||||
// 介于/不介于 的边界包含控制,默认 true
|
||||
public bool IncludeLowerBound { get; set; } = true;
|
||||
public bool IncludeUpperBound { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string ScopeClientIds { get; set; }
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,7 +845,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
return false;
|
||||
}
|
||||
|
||||
if (application.ScopeIsGlobal)
|
||||
if (application.ScopeIsGlobal == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
public class RiskRule
|
||||
{
|
||||
// === 基础信息 ===
|
||||
public int Id { get; set; }
|
||||
public long Id { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// 应用配置主键ID。
|
||||
/// 用于唯一标识一条规则应用记录。
|
||||
/// </summary>
|
||||
public int Id { get; set; }
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 关联的规则ID列表。
|
||||
@@ -67,7 +67,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// true 表示对所有交易都适用,此时通常忽略其他 Scope 字段;
|
||||
/// false 表示只在指定范围内适用,需要结合下方各 Scope 字段进行过滤。
|
||||
/// </summary>
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ScopeIsGlobal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 适用的资产簿记账户范围。
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using BaseOUDAL;
|
||||
using Newtonsoft.Json;
|
||||
using Qdp.Foundation.Utilities;
|
||||
using System.Linq.Expressions;
|
||||
using YLErp.BLL;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Model;
|
||||
@@ -202,7 +203,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
private static readonly Dictionary<RiskVariableDataType, HashSet<string>> ValidOperatorsByType = new Dictionary<RiskVariableDataType, HashSet<string>>
|
||||
{
|
||||
{ RiskVariableDataType.Numeric, new HashSet<string> { ">", "<", ">=", "<=", "=", "≠", "介于", "不介于" } },
|
||||
{ RiskVariableDataType.Date, new HashSet<string> { "<", ">", "=", ">=", "<=", "介于", "不介于" } },
|
||||
{ RiskVariableDataType.Date, new HashSet<string> { "早于", "晚于", "等于", "不早于", "不晚于", "介于", "不介于" } },
|
||||
{ RiskVariableDataType.Boolean, new HashSet<string> { "是", "否" } }
|
||||
};
|
||||
|
||||
@@ -291,15 +292,35 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
if (cond.Value == null)
|
||||
throw new ServiceException($"{condLabel}:固定阈值不能为空");
|
||||
if (variableDef.DataType == RiskVariableDataType.Numeric)
|
||||
|
||||
if (cond.Operator == "介于" || cond.Operator == "不介于")
|
||||
{
|
||||
if (!decimal.TryParse(cond.Value.ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:数值型变量的阈值必须为数字");
|
||||
// 介于/不介于:Value 必须为双元素数组 [下限, 上限]
|
||||
if (!(cond.Value is Newtonsoft.Json.Linq.JArray arr && arr.Count == 2))
|
||||
throw new ServiceException($"{condLabel}:操作符 '{cond.Operator}' 的阈值必须为双元素数组 [下限, 上限]");
|
||||
if (variableDef.DataType == RiskVariableDataType.Numeric)
|
||||
{
|
||||
if (!decimal.TryParse(arr[0].ToString(), out _) || !decimal.TryParse(arr[1].ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:数值型介于/不介于的下限和上限必须为数字");
|
||||
}
|
||||
if (variableDef.DataType == RiskVariableDataType.Date)
|
||||
{
|
||||
if (!DateTime.TryParse(arr[0].ToString(), out _) || !DateTime.TryParse(arr[1].ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:日期型介于/不介于的起始和结束日期必须为合法日期");
|
||||
}
|
||||
}
|
||||
if (variableDef.DataType == RiskVariableDataType.Date)
|
||||
else
|
||||
{
|
||||
if (!DateTime.TryParse(cond.Value.ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:日期型变量的阈值必须为合法日期");
|
||||
if (variableDef.DataType == RiskVariableDataType.Numeric)
|
||||
{
|
||||
if (!decimal.TryParse(cond.Value.ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:数值型变量的阈值必须为数字");
|
||||
}
|
||||
if (variableDef.DataType == RiskVariableDataType.Date)
|
||||
{
|
||||
if (!DateTime.TryParse(cond.Value.ToString(), out _))
|
||||
throw new ServiceException($"{condLabel}:日期型变量的阈值必须为合法日期");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cond.ThresholdType == "Variable")
|
||||
@@ -356,7 +377,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
|
||||
private void ValidateScopeFields(CreateRiskApplicationReq req)
|
||||
{
|
||||
if (req.ScopeIsGlobal)
|
||||
if (req.ScopeIsGlobal == 1)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(req.ScopeAssetBookIds) ||
|
||||
!string.IsNullOrEmpty(req.ScopeClientIds) ||
|
||||
@@ -513,6 +534,71 @@ namespace YLErp.Modules.RiskEngine
|
||||
return string.Join(", ", names);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 构建 Scope 字段的 OR 过滤谓词(逗号分隔值精确匹配)
|
||||
/// </summary>
|
||||
private static IQueryable<glms_risk_rule_application> ApplyScopeFilter(
|
||||
IQueryable<glms_risk_rule_application> query,
|
||||
Expression<Func<glms_risk_rule_application, string>> fieldSelector,
|
||||
string csvValues)
|
||||
{
|
||||
var ids = csvValues.Split(',', StringSplitOptions.RemoveEmptyEntries);
|
||||
if (ids.Length == 0)
|
||||
return query;
|
||||
|
||||
Expression<Func<glms_risk_rule_application, bool>> predicate = null;
|
||||
var param = fieldSelector.Parameters[0];
|
||||
var member = fieldSelector.Body;
|
||||
|
||||
foreach (var trimmed in ids.Select(id => id.Trim()))
|
||||
{
|
||||
var eq = Expression.Equal(member, Expression.Constant(trimmed));
|
||||
var startsExpr = Expression.Call(member, nameof(string.StartsWith), null,
|
||||
Expression.Constant(trimmed + ","));
|
||||
var endsExpr = Expression.Call(member, nameof(string.EndsWith), null,
|
||||
Expression.Constant("," + trimmed));
|
||||
var containsExpr = Expression.Call(member, nameof(string.Contains), null,
|
||||
Expression.Constant("," + trimmed + ","));
|
||||
|
||||
var orExpr = Expression.OrElse(Expression.OrElse(eq, startsExpr),
|
||||
Expression.OrElse(endsExpr, containsExpr));
|
||||
var lambda = Expression.Lambda<Func<glms_risk_rule_application, bool>>(orExpr, param);
|
||||
predicate = predicate == null ? lambda : predicate.Or(lambda);
|
||||
}
|
||||
|
||||
return predicate != null ? query.Where(predicate) : query;
|
||||
}
|
||||
|
||||
private static string GetStrategyName(RiskControlStrategy strategy)
|
||||
{
|
||||
return strategy switch
|
||||
{
|
||||
RiskControlStrategy.Block => "阻断",
|
||||
RiskControlStrategy.Approval => "审批",
|
||||
RiskControlStrategy.ShowTip => "提醒",
|
||||
_ => strategy.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private static readonly Dictionary<string, string> TriggerPointCnMap = new Dictionary<string, string>
|
||||
{
|
||||
["BOOK_CONFIRM"] = "交易录入确认",
|
||||
["CLOSE_REVIEW"] = "平仓审核",
|
||||
["UPLOAD_CONFIRMATION"] = "上传确认书",
|
||||
["EVENT_TRIGGER"] = "事件触发",
|
||||
["FUND_PAYMENT"] = "资金支付"
|
||||
};
|
||||
|
||||
private static string MapTriggerPointsToChinese(string triggerPoints)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(triggerPoints))
|
||||
return "";
|
||||
|
||||
var parts = triggerPoints.Split(',');
|
||||
var translated = parts.Select(p => TriggerPointCnMap.TryGetValue(p.Trim(), out var cn) ? cn : p.Trim());
|
||||
return string.Join(", ", translated);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Rule Management
|
||||
@@ -813,7 +899,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
Id = app.id,
|
||||
RuleIds = app.RuleIds,
|
||||
Status = app.Status,
|
||||
Status = (int)app.Status,
|
||||
ControlStrategy = app.ControlStrategy,
|
||||
TriggerPoints = app.TriggerPoints,
|
||||
ScopeAssetBookIds = app.ScopeAssetBookIds,
|
||||
@@ -878,12 +964,24 @@ namespace YLErp.Modules.RiskEngine
|
||||
&& r.RuleName.Contains(req.RuleName)));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.ScopeClientIds))
|
||||
query = ApplyScopeFilter(query, a => a.ScopeClientIds, req.ScopeClientIds);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.ScopeUnderlyingTypes))
|
||||
query = ApplyScopeFilter(query, a => a.ScopeUnderlyingTypes, req.ScopeUnderlyingTypes);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.ScopeTradeTypes))
|
||||
query = ApplyScopeFilter(query, a => a.ScopeTradeTypes, req.ScopeTradeTypes);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.ScopeAssetBookIds))
|
||||
query = ApplyScopeFilter(query, a => a.ScopeAssetBookIds, req.ScopeAssetBookIds);
|
||||
|
||||
var pagedResult = query.OrderByDescending(a => a.UpdateDate)
|
||||
.Select(a => new RiskApplicationListItem
|
||||
{
|
||||
Id = a.id,
|
||||
RuleIds = a.RuleIds,
|
||||
Status = a.Status,
|
||||
Status = (int)a.Status,
|
||||
ControlStrategy = a.ControlStrategy,
|
||||
TriggerPoints = a.TriggerPoints,
|
||||
ScopeAssetBookIds = a.ScopeAssetBookIds,
|
||||
@@ -962,7 +1060,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
DbContext.SaveChanges();
|
||||
|
||||
WriteAuditLog("APP_CREATE", "APPLICATION", entity.id, ResolveRuleNames(req.RuleIds),
|
||||
$"创建应用配置:策略={req.ControlStrategy}, 触发时点={req.TriggerPoints}",
|
||||
$"创建应用配置:策略={GetStrategyName(req.ControlStrategy)}, 触发时点={MapTriggerPointsToChinese(req.TriggerPoints)}",
|
||||
snapshotData: JsonConvert.SerializeObject(new { Version = entity.Version }));
|
||||
DbContext.SaveChanges();
|
||||
|
||||
@@ -1016,7 +1114,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
app.UpdateDate = DateTime.Now;
|
||||
|
||||
WriteAuditLog("APP_UPDATE", "APPLICATION", applicationId, ResolveRuleNames(app.RuleIds),
|
||||
$"修改应用配置:策略={req.ControlStrategy}, 触发时点={req.TriggerPoints}");
|
||||
$"修改应用配置:策略={GetStrategyName(req.ControlStrategy)}, 触发时点={MapTriggerPointsToChinese(req.TriggerPoints)}");
|
||||
DbContext.SaveChanges();
|
||||
|
||||
TryRefreshCache();
|
||||
@@ -1034,7 +1132,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
|
||||
WriteAuditLog("APPLICATION_DELETE", "APPLICATION", applicationId, ResolveRuleNames(app.RuleIds), "删除应用配置");
|
||||
WriteAuditLog("APP_DELETE", "APPLICATION", applicationId, ResolveRuleNames(app.RuleIds), "删除应用配置");
|
||||
DbContext.SaveChanges();
|
||||
|
||||
TryRefreshCache();
|
||||
@@ -1127,7 +1225,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
|
||||
WriteAuditLog("APPLICATION_BATCH_DISABLE", "APPLICATION", app.id, ResolveRuleNames(app.RuleIds), "批量停用应用配置");
|
||||
WriteAuditLog("APP_BATCH_DISABLE", "APPLICATION", app.id, ResolveRuleNames(app.RuleIds), "批量停用应用配置");
|
||||
}
|
||||
|
||||
DbContext.SaveChanges();
|
||||
@@ -1154,6 +1252,11 @@ namespace YLErp.Modules.RiskEngine
|
||||
query = query.Where(v => v.Category == req.Category.Value);
|
||||
}
|
||||
|
||||
if (req.DataType.HasValue)
|
||||
{
|
||||
query = query.Where(v => v.DataType == req.DataType.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.VariableName))
|
||||
{
|
||||
query = query.Where(v => v.VariableName.Contains(req.VariableName));
|
||||
@@ -1358,19 +1461,36 @@ namespace YLErp.Modules.RiskEngine
|
||||
query = query.Where(l => l.OperationType == req.OperationType);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.OperationTypes))
|
||||
{
|
||||
var types = req.OperationTypes.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||
query = query.Where(l => types.Contains(l.OperationType));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.TargetType))
|
||||
{
|
||||
query = query.Where(l => l.TargetType == req.TargetType);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.TargetName))
|
||||
{
|
||||
query = query.Where(l => l.TargetName.Contains(req.TargetName));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.OptName))
|
||||
{
|
||||
query = query.Where(l => l.OptName.Contains(req.OptName));
|
||||
}
|
||||
|
||||
if (req.StartDate.HasValue)
|
||||
{
|
||||
query = query.Where(l => l.OptDate >= req.StartDate.Value);
|
||||
query = query.Where(l => l.OptDate >= req.StartDate.Value.Date);
|
||||
}
|
||||
|
||||
if (req.EndDate.HasValue)
|
||||
{
|
||||
query = query.Where(l => l.OptDate <= req.EndDate.Value);
|
||||
var end = req.EndDate.Value.Date.AddDays(1);
|
||||
query = query.Where(l => l.OptDate < end);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.Keyword))
|
||||
|
||||
@@ -62,21 +62,21 @@
|
||||
<FunctionSub Name="观察事件" Title="观察事件"></FunctionSub>
|
||||
<FunctionSub Name="风险预警/禁止查询" Title="风险预警/禁止查询"></FunctionSub>
|
||||
<FunctionSub Name="异常交易监控" Title="异常交易监控"></FunctionSub>
|
||||
<FunctionSub Name="风控规则查看" Title="规则管理Tab" Note="控制规则管理Tab可见性"></FunctionSub>
|
||||
<FunctionSub Name="风控规则查看" Type="Operate" Note="是否有权限查询风控规则"></FunctionSub>
|
||||
<FunctionSub Name="风控规则新增" Type="Operate" Note="是否有权限新增风控规则"></FunctionSub>
|
||||
<FunctionSub Name="风控规则编辑" Type="Operate" Note="是否有权限编辑风控规则"></FunctionSub>
|
||||
<FunctionSub Name="风控规则删除" Type="Operate" Note="是否有权限删除/批量删除风控规则"></FunctionSub>
|
||||
<FunctionSub Name="风控规则启停" Type="Operate" Note="是否有权限启用/停用风控规则"></FunctionSub>
|
||||
<FunctionSub Name="风控应用查看" Title="规则应用Tab" Note="控制规则应用Tab可见性"></FunctionSub>
|
||||
<FunctionSub Name="风控应用查看" Type="Operate" Note="是否有权限查询风控应用"></FunctionSub>
|
||||
<FunctionSub Name="风控应用新增" Type="Operate" Note="是否有权限新增应用配置"></FunctionSub>
|
||||
<FunctionSub Name="风控应用编辑" Type="Operate" Note="是否有权限编辑应用配置"></FunctionSub>
|
||||
<FunctionSub Name="风控应用删除" Type="Operate" Note="是否有权限删除应用配置"></FunctionSub>
|
||||
<FunctionSub Name="风控应用启停" Type="Operate" Note="是否有权限启用/停用/批量操作应用配置"></FunctionSub>
|
||||
<FunctionSub Name="风控变量查看" Title="变量池Tab" Note="控制变量池Tab可见性"></FunctionSub>
|
||||
<FunctionSub Name="风控变量查看" Type="Operate" Note="是否有权限查询风控变量"></FunctionSub>
|
||||
<FunctionSub Name="风控变量新增" Type="Operate" Note="是否有权限新增变量"></FunctionSub>
|
||||
<FunctionSub Name="风控变量编辑" Type="Operate" Note="是否有权限编辑变量"></FunctionSub>
|
||||
<FunctionSub Name="风控变量删除" Type="Operate" Note="是否有权限删除变量"></FunctionSub>
|
||||
<FunctionSub Name="风控日志查看" Title="操作日志Tab" Note="控制操作日志Tab可见性"></FunctionSub>
|
||||
<FunctionSub Name="风控日志查看" Type="Operate" Note="是否有权限查询风控日志"></FunctionSub>
|
||||
<FunctionSub Name="风控日志导出" Type="Operate" Note="是否有权限导出日志Excel"></FunctionSub>
|
||||
</FunctionParent>
|
||||
<FunctionParent Name="结算管理" Title="结算财务">
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
{Name:"资金监控",Rights:["风险控制-资金监控"],Url:"client/clientRiskMonitor"},
|
||||
{Name:"市场风险",Rights:["风险控制-市场风险"],Url:"risk/RiskExposureReport"},
|
||||
{Name:"限额监控",Rights:["风险控制-限额监控"],Url:"risk/quotaMonitor"},
|
||||
{Name:"异常交易监控",Rights:["风险控制-异常交易监控"],Url:"v3/risk/risk-engine-config"},
|
||||
{Name:"白名单券池",Rights:["风险控制-白名单券池"],Url:"v3/data/underlying-pool"},
|
||||
{Name:"日终持仓风险",Rights:["风险控制-日终持仓风险"],Url:"trade/EodPositionRisks"},
|
||||
{Name:"日终持仓风险_互换",Rights:["风险控制-日终持仓风险_互换"],Url:"swaptrade2/EodPositionRisks"},
|
||||
|
||||
@@ -180,14 +180,6 @@ namespace YLErp.Web
|
||||
return;
|
||||
}
|
||||
var hasRight = false;
|
||||
#if DEBUG
|
||||
if (context.Controller is Controllers.RiskRuleController)
|
||||
{
|
||||
hasRight = true;
|
||||
base.OnActionExecuting(context);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
var isAjaxRequest = Request.Headers["X-Requested-With"] == "XMLHttpRequest";
|
||||
var typedHeaders = Request.GetTypedHeaders();
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using Qdp.Foundation.Utilities;
|
||||
using Qdp.Foundation.Utilities;
|
||||
using YLErp.DBModels;
|
||||
using YLErp.Modules.RiskEngine;
|
||||
using YLErp.Modules.RiskEngine.Dto;
|
||||
@@ -13,7 +13,7 @@ namespace YLErp.Web.Controllers
|
||||
#region Rule Management
|
||||
|
||||
[HttpGet("risk-rules")]
|
||||
[MyAuthorize("风控规则查看")]
|
||||
[MyAuthorize("风险控制-风控规则查看")]
|
||||
public JsonResult QueryRiskRules(QueryRiskRuleReq req)
|
||||
{
|
||||
try
|
||||
@@ -34,7 +34,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-rules/{id}")]
|
||||
[MyAuthorize("风控规则查看")]
|
||||
[MyAuthorize("风险控制-风控规则查看")]
|
||||
public JsonResult GetRiskRule(long id)
|
||||
{
|
||||
try
|
||||
@@ -55,7 +55,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-rules/{id}/versions")]
|
||||
[MyAuthorize("风控规则查看")]
|
||||
[MyAuthorize("风险控制-风控规则查看")]
|
||||
public JsonResult GetRiskRuleVersions(long id)
|
||||
{
|
||||
try
|
||||
@@ -76,7 +76,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-rules")]
|
||||
[MyAuthorize("风控规则新增")]
|
||||
[MyAuthorize("风险控制-风控规则新增")]
|
||||
public JsonResult CreateRiskRule([FromBody] CreateRiskRuleReq req)
|
||||
{
|
||||
try
|
||||
@@ -97,7 +97,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPut("risk-rules/{id}")]
|
||||
[MyAuthorize("风控规则编辑")]
|
||||
[MyAuthorize("风险控制-风控规则编辑")]
|
||||
public JsonResult UpdateRiskRule(long id, [FromBody] UpdateRiskRuleReq req)
|
||||
{
|
||||
try
|
||||
@@ -118,7 +118,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpDelete("risk-rules/{id}")]
|
||||
[MyAuthorize("风控规则删除")]
|
||||
[MyAuthorize("风险控制-风控规则删除")]
|
||||
public JsonResult DeleteRiskRule(long id)
|
||||
{
|
||||
try
|
||||
@@ -139,7 +139,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpDelete("risk-rules/batch")]
|
||||
[MyAuthorize("风控规则删除")]
|
||||
[MyAuthorize("风险控制-风控规则删除")]
|
||||
public JsonResult BatchDeleteRiskRules([FromBody] List<long> ids)
|
||||
{
|
||||
try
|
||||
@@ -160,7 +160,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-rules/{id}/enable")]
|
||||
[MyAuthorize("风控规则启停")]
|
||||
[MyAuthorize("风险控制-风控规则启停")]
|
||||
public JsonResult EnableRiskRule(long id)
|
||||
{
|
||||
try
|
||||
@@ -181,7 +181,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-rules/{id}/disable")]
|
||||
[MyAuthorize("风控规则启停")]
|
||||
[MyAuthorize("风险控制-风控规则启停")]
|
||||
public JsonResult DisableRiskRule(long id)
|
||||
{
|
||||
try
|
||||
@@ -202,7 +202,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-rules/{id}/applications")]
|
||||
[MyAuthorize("风控规则查看")]
|
||||
[MyAuthorize("风险控制-风控规则查看")]
|
||||
public JsonResult GetRuleApplications(long id)
|
||||
{
|
||||
try
|
||||
@@ -223,7 +223,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-rules/list")]
|
||||
[MyAuthorize("风控规则查看")]
|
||||
[MyAuthorize("风险控制-风控规则查看")]
|
||||
public JsonResult GetAllRiskRules()
|
||||
{
|
||||
try
|
||||
@@ -248,7 +248,7 @@ namespace YLErp.Web.Controllers
|
||||
#region Application Management
|
||||
|
||||
[HttpGet("risk-applications")]
|
||||
[MyAuthorize("风控应用查看")]
|
||||
[MyAuthorize("风险控制-风控应用查看")]
|
||||
public JsonResult QueryRiskApplications(QueryRiskApplicationReq req)
|
||||
{
|
||||
try
|
||||
@@ -269,7 +269,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-applications/{id}")]
|
||||
[MyAuthorize("风控应用查看")]
|
||||
[MyAuthorize("风险控制-风控应用查看")]
|
||||
public JsonResult GetRiskApplication(long id)
|
||||
{
|
||||
try
|
||||
@@ -290,7 +290,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-applications")]
|
||||
[MyAuthorize("风控应用新增")]
|
||||
[MyAuthorize("风险控制-风控应用新增")]
|
||||
public JsonResult CreateRiskApplication([FromBody] CreateRiskApplicationReq req)
|
||||
{
|
||||
try
|
||||
@@ -311,7 +311,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPut("risk-applications/{id}")]
|
||||
[MyAuthorize("风控应用编辑")]
|
||||
[MyAuthorize("风险控制-风控应用编辑")]
|
||||
public JsonResult UpdateRiskApplication(long id, [FromBody] UpdateRiskApplicationReq req)
|
||||
{
|
||||
try
|
||||
@@ -332,7 +332,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpDelete("risk-applications/{id}")]
|
||||
[MyAuthorize("风控应用删除")]
|
||||
[MyAuthorize("风险控制-风控应用删除")]
|
||||
public JsonResult DeleteRiskApplication(long id)
|
||||
{
|
||||
try
|
||||
@@ -353,7 +353,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-applications/{id}/enable")]
|
||||
[MyAuthorize("风控应用启停")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
public JsonResult EnableRiskApplication(long id)
|
||||
{
|
||||
try
|
||||
@@ -374,7 +374,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-applications/{id}/disable")]
|
||||
[MyAuthorize("风控应用启停")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
public JsonResult DisableRiskApplication(long id)
|
||||
{
|
||||
try
|
||||
@@ -395,7 +395,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-applications/batch-enable")]
|
||||
[MyAuthorize("风控应用启停")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
public JsonResult BatchEnableRiskApplications([FromBody] List<long> ids)
|
||||
{
|
||||
try
|
||||
@@ -416,7 +416,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-applications/batch-disable")]
|
||||
[MyAuthorize("风控应用启停")]
|
||||
[MyAuthorize("风险控制-风控应用启停")]
|
||||
public JsonResult BatchDisableRiskApplications([FromBody] List<long> ids)
|
||||
{
|
||||
try
|
||||
@@ -441,7 +441,7 @@ namespace YLErp.Web.Controllers
|
||||
#region Variable Management
|
||||
|
||||
[HttpGet("risk-variables")]
|
||||
[MyAuthorize("风控变量查看")]
|
||||
[MyAuthorize("风险控制-风控变量查看")]
|
||||
public JsonResult QueryRiskVariables(QueryRiskVariableReq req)
|
||||
{
|
||||
try
|
||||
@@ -462,7 +462,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-variables/{id}")]
|
||||
[MyAuthorize("风控变量查看")]
|
||||
[MyAuthorize("风险控制-风控变量查看")]
|
||||
public JsonResult GetRiskVariable(long id)
|
||||
{
|
||||
try
|
||||
@@ -483,7 +483,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-variables/list")]
|
||||
[MyAuthorize("风控变量查看")]
|
||||
[MyAuthorize("风险控制-风控变量查看")]
|
||||
public JsonResult GetAllRiskVariables()
|
||||
{
|
||||
try
|
||||
@@ -504,7 +504,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPost("risk-variables")]
|
||||
[MyAuthorize("风控变量新增")]
|
||||
[MyAuthorize("风险控制-风控变量新增")]
|
||||
public JsonResult CreateRiskVariable([FromBody] CreateRiskVariableReq req)
|
||||
{
|
||||
try
|
||||
@@ -525,7 +525,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpPut("risk-variables/{id}")]
|
||||
[MyAuthorize("风控变量编辑")]
|
||||
[MyAuthorize("风险控制-风控变量编辑")]
|
||||
public JsonResult UpdateRiskVariable(long id, [FromBody] UpdateRiskVariableReq req)
|
||||
{
|
||||
try
|
||||
@@ -546,7 +546,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpDelete("risk-variables/{id}")]
|
||||
[MyAuthorize("风控变量删除")]
|
||||
[MyAuthorize("风险控制-风控变量删除")]
|
||||
public JsonResult DeleteRiskVariable(long id)
|
||||
{
|
||||
try
|
||||
@@ -595,7 +595,7 @@ namespace YLErp.Web.Controllers
|
||||
#region Trade Types
|
||||
|
||||
[HttpGet("trade-types")]
|
||||
[MyAuthorize("风控应用查看")]
|
||||
[MyAuthorize("风险控制-风控应用查看")]
|
||||
public JsonResult GetTradeTypes()
|
||||
{
|
||||
try
|
||||
@@ -624,7 +624,7 @@ namespace YLErp.Web.Controllers
|
||||
#region Audit Log
|
||||
|
||||
[HttpGet("risk-audit-logs")]
|
||||
[MyAuthorize("风控日志查看")]
|
||||
[MyAuthorize("风险控制-风控日志查看")]
|
||||
public JsonResult QueryRiskAuditLogs(QueryRiskAuditLogReq req)
|
||||
{
|
||||
try
|
||||
@@ -645,7 +645,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-audit-logs/{id}")]
|
||||
[MyAuthorize("风控日志查看")]
|
||||
[MyAuthorize("风险控制-风控日志查看")]
|
||||
public JsonResult GetRiskAuditLogDetail(long id)
|
||||
{
|
||||
try
|
||||
@@ -666,7 +666,7 @@ namespace YLErp.Web.Controllers
|
||||
}
|
||||
|
||||
[HttpGet("risk-audit-logs/export")]
|
||||
[MyAuthorize("风控日志导出")]
|
||||
[MyAuthorize("风险控制-风控日志导出")]
|
||||
public IActionResult ExportRiskAuditLogs(QueryRiskAuditLogReq req)
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user