feat(risk-engine): 完善风控规则种子数据与 CRUD 接口优化
1. 新增 21 条通用风控规则及应用配置种子数据(seed_rules.sql / seed_applications.sql) 2. 新增 9 个风控变量(偏离度类、执行价、最低保证金率、参考价格) 3. DTO 字段重命名:ExpectedVersion → Version,Keyword → RuleName/VariableName 4. 规则列表返回 ConditionJson 和 RuleExpr 字段 5. 应用列表查询支持按规则名称数据库级筛选(替代内存过滤) 6. 启用/停用操作不再递增 Version 号 7. RiskEngineService 单例构造使用 SystemUser 替代 null 8. RiskRuleService 移除冗余实例字段,改用 GetInstance() 直接调用
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
-- ============================================================
|
||||
-- 规则应用初始数据(对应设计文档 §4.9.1 通用规则预置参考)
|
||||
-- 依赖:seed_rules.sql(规则数据需先插入)
|
||||
--
|
||||
-- 每条规则对应一条应用配置(1:1),定义"何时、对谁、怎么处理"
|
||||
-- ControlStrategy: 1=Block(禁止), 2=Approval(审批), 3=Warning(提示)
|
||||
-- TriggerPoints: BOOK_CONFIRM=簿记交易确认
|
||||
-- ScopeIsGlobal: 1=全局适用, 0=按维度配置(Scope字段为空表示"全部")
|
||||
-- ============================================================
|
||||
|
||||
-- 规则1:挂钩标的集中度超阈值(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '挂钩标的集中度超阈值';
|
||||
|
||||
-- 规则2:挂钩标的到期日小于合约到期日(禁止,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 1, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '挂钩标的到期日小于合约到期日';
|
||||
|
||||
-- 规则3:名义本金超阈值(审批,账户/合约类型)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '名义本金超阈值';
|
||||
|
||||
-- 规则4:保证金支付比例超阈值(审批,账户/标的类型)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '保证金支付比例超阈值';
|
||||
|
||||
-- 规则5:保证金利率偏离(审批,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '保证金利率偏离';
|
||||
|
||||
-- 规则6:保证金收取比例低于最低标准(审批,账户/标的类型)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '保证金收取比例低于最低标准';
|
||||
|
||||
-- 规则7:起息日早于当前日期(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '起息日早于当前日期';
|
||||
|
||||
-- 规则8:支付日为银行间交易日(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '支付日为银行间交易日';
|
||||
|
||||
-- 规则9:到期日为银行间交易日(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '到期日为银行间交易日';
|
||||
|
||||
-- 规则10:平仓日为银行间交易日(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '平仓日为银行间交易日';
|
||||
|
||||
-- 规则11:合约期限超阈值(审批,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '合约期限超阈值';
|
||||
|
||||
-- 规则12:债券类净价偏离(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '债券类净价偏离';
|
||||
|
||||
-- 规则13:债券类收益率偏离(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '债券类收益率偏离';
|
||||
|
||||
-- 规则14:非债券类价格偏离(审批,全局)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '非债券类价格偏离';
|
||||
|
||||
-- 规则15:单一交易对手累计标的数量超阈值(审批,对手方)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '单一交易对手累计标的数量超阈值';
|
||||
|
||||
-- 规则16:多头支付固定端利率偏离(审批,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '多头支付固定端利率偏离';
|
||||
|
||||
-- 规则17:空头利率减点借贷加权偏离(审批,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '空头利率减点借贷加权偏离';
|
||||
|
||||
-- 规则18:账户授权收支方向不匹配(禁止,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 1, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '账户授权收支方向不匹配';
|
||||
|
||||
-- 规则19:执行价偏离超阈值(审批,账户)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 2, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '执行价偏离超阈值';
|
||||
|
||||
-- 规则20:希腊字母限额超阈值(提示,账户/标的,预留接口)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 3, 'BOOK_CONFIRM', 0, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '希腊字母限额超阈值';
|
||||
|
||||
-- 规则21:接近/触发敲入敲出价(提示,全局,预留接口)
|
||||
INSERT INTO `glms_risk_rule_application` (`RuleIds`, `Status`, `ControlStrategy`, `TriggerPoints`, `ScopeIsGlobal`, `Version`, `OptId`, `OptName`, `OptDate`)
|
||||
SELECT
|
||||
CAST(r.id AS CHAR), 1, 3, 'BOOK_CONFIRM', 1, 1, 0, 'SYSTEM', NOW()
|
||||
FROM `glms_risk_rule` r WHERE r.RuleName = '接近/触发敲入敲出价';
|
||||
@@ -0,0 +1,306 @@
|
||||
-- ============================================================
|
||||
-- 规则初始数据(对应设计文档 §4.9.1 通用规则预置参考)
|
||||
-- 依赖:seed_variables.sql(变量池数据需先插入,ID 1~44)
|
||||
--
|
||||
-- 变量 ID 映射(seed_variables.sql 自增):
|
||||
-- 1=合约名义本金 2=合约起息日 3=合约到期日 4=合约平仓日
|
||||
-- 5=合约支付日 6=期初净价 7=期初全价 8=期初收益率
|
||||
-- 9=期初价格 10=期末全价 11=期末价格 12=保证金利率
|
||||
-- 13=保证金比例 14=客户授信额度
|
||||
-- 15=上一收盘日中债估值净价 16=上一收盘日中债估值全价 17=上一收盘日中债估值收益率
|
||||
-- 18=上一日收盘价 19=借贷加权费率 20=FR007 21=当前日期
|
||||
-- 22=挂钩标的到期日 23=标的发行余额
|
||||
-- 24=挂钩标的集中度 25=授信占用率 26=合约期限 27=Delta
|
||||
-- 28=Gamma 29=Vega 30=Theta 31=利息端利率
|
||||
-- 32=对手方累计标的数量 33=同一标的累计名义本金 34=同一客户累计名义本金
|
||||
-- 35=总持仓名义本金
|
||||
-- 36=到期日是否银行间交易日 37=平仓日是否银行间交易日 38=支付日是否银行间交易日
|
||||
-- 39=利息端/浮动端方向是否同向 40=关键业务要素是否一致
|
||||
-- 41=多空方向为多头 42=多空方向为空头
|
||||
-- 43=保证金收支方向为支付 44=保证金收支方向为收取
|
||||
-- 45=期初净价偏离度 46=期初收益率偏离度 47=期初价格偏离度
|
||||
-- 48=利息端利率与FR007偏离度 49=利息端利率与借贷加权费率偏离度
|
||||
-- 50=执行价偏离度 51=执行价 52=客户品种最低保证金率 53=参考价格
|
||||
-- ============================================================
|
||||
|
||||
|
||||
-- ============================================================
|
||||
-- 插入 21 条通用规则
|
||||
-- ============================================================
|
||||
|
||||
-- 规则1:挂钩标的集中度超阈值(审批,全局)
|
||||
-- 条件:挂钩标的集中度(ID=24) > 30%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('挂钩标的集中度超阈值',
|
||||
'挂钩标的集中度超过阈值(默认30%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 24, 'VariableName', '挂钩标的集中度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 30,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'calc.UnderlyingConcentration > 30',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则2:挂钩标的到期日小于合约到期日(禁止,全局)
|
||||
-- 条件:挂钩标的到期日(ID=22) < 合约到期日(ID=3)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('挂钩标的到期日小于合约到期日',
|
||||
'挂钩标的到期日早于合约到期日时禁止交易',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 22, 'VariableName', '挂钩标的到期日', 'VariableType', 'Date',
|
||||
'Operator', '<', 'ThresholdType', 'variable', 'Value', JSON_TYPE(NULL),
|
||||
'ThresholdVariableId', 3, 'ThresholdVariableName', '合约到期日', 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'market.UnderlyingMaturityDate < trade.ExerciseDate',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则3:名义本金超阈值(审批,账户/合约类型)
|
||||
-- 条件:合约名义本金(ID=1) > 100000000(1亿元)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('名义本金超阈值',
|
||||
'合约名义本金超过阈值(默认1亿元)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 1, 'VariableName', '合约名义本金', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 100000000,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '元'
|
||||
)),
|
||||
'trade.StockEqvNotional > 100000000',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则4:保证金支付比例超阈值(审批,账户/标的类型)
|
||||
-- 条件:保证金比例(ID=13) > 50%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('保证金支付比例超阈值',
|
||||
'保证金比例超过阈值(默认50%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 13, 'VariableName', '保证金比例', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 50,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'trade.MarginRate > 50',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则5:保证金利率偏离(审批,账户)
|
||||
-- 条件:保证金利率(ID=12) 不介于 [2%, 5%]
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('保证金利率偏离',
|
||||
'保证金利率不在配置区间内(默认2%~5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 12, 'VariableName', '保证金利率', 'VariableType', 'Numeric',
|
||||
'Operator', '不介于', 'ThresholdType', 'fixed', 'Value', JSON_ARRAY(2, 5),
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'!(client_marginrate.InitMarginRebateRate >= 2 && client_marginrate.InitMarginRebateRate <= 5)',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则6:保证金收取比例低于最低标准(审批,账户/标的类型)
|
||||
-- 条件:保证金比例(ID=13) < 客户品种最低保证金率(ID=52)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('保证金收取比例低于最低标准',
|
||||
'保证金比例低于客户品种最低保证金率时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 13, 'VariableName', '保证金比例', 'VariableType', 'Numeric',
|
||||
'Operator', '<', 'ThresholdType', 'variable', 'Value', JSON_TYPE(NULL),
|
||||
'ThresholdVariableId', 52, 'ThresholdVariableName', '客户品种最低保证金率', 'Unit', '%'
|
||||
)),
|
||||
'trade.MarginRate < config.MinMarginRate',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则7:起息日早于当前日期(审批,全局)
|
||||
-- 条件:合约起息日(ID=2) < 当前日期(ID=21)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('起息日早于当前日期',
|
||||
'合约起息日早于当前日期时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 2, 'VariableName', '合约起息日', 'VariableType', 'Date',
|
||||
'Operator', '<', 'ThresholdType', 'variable', 'Value', JSON_TYPE(NULL),
|
||||
'ThresholdVariableId', 21, 'ThresholdVariableName', '当前日期', 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'trade.StartDate < sys.CurrentDate',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则8:支付日为银行间交易日(审批,全局)
|
||||
-- 条件:支付日是否银行间交易日(ID=38) = 是
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('支付日为银行间交易日',
|
||||
'支付日为银行间交易日时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 38, 'VariableName', '支付日是否银行间交易日', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'calc.IsSettlementDateTradingDay == true',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则9:到期日为银行间交易日(审批,全局)
|
||||
-- 条件:到期日是否银行间交易日(ID=36) = 是
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('到期日为银行间交易日',
|
||||
'到期日为银行间交易日时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 36, 'VariableName', '到期日是否银行间交易日', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'calc.IsExerciseDateTradingDay == true',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则10:平仓日为银行间交易日(审批,全局)
|
||||
-- 条件:平仓日是否银行间交易日(ID=37) = 是
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('平仓日为银行间交易日',
|
||||
'平仓日为银行间交易日时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 37, 'VariableName', '平仓日是否银行间交易日', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'calc.IsUnwindDateTradingDay == true',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则11:合约期限超阈值(审批,账户)
|
||||
-- 条件:合约期限(ID=26) > 365天
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('合约期限超阈值',
|
||||
'合约期限超过阈值(默认365天)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 26, 'VariableName', '合约期限', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 365,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '天'
|
||||
)),
|
||||
'calc.MaturityDays > 365',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则12:债券类净价偏离(审批,全局)
|
||||
-- 条件:期初净价偏离度(ID=45) > 5%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('债券类净价偏离',
|
||||
'期初净价与上一收盘日中债估值净价偏离度超阈值(默认5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 45, 'VariableName', '期初净价偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 5,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'Math.Abs(swap_position.PosiNetNoFeePrice - market.CBValuationNetPrice) / market.CBValuationNetPrice * 100 > 5',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则13:债券类收益率偏离(审批,全局)
|
||||
-- 条件:期初收益率偏离度(ID=46) > 5%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('债券类收益率偏离',
|
||||
'期初收益率与上一收盘日中债估值收益率偏离度超阈值(默认5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 46, 'VariableName', '期初收益率偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 5,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'Math.Abs(trade.InitYtm - market.CBValuationYtm) / market.CBValuationYtm * 100 > 5',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则14:非债券类价格偏离(审批,全局)
|
||||
-- 条件:期初价格偏离度(ID=47) > 5%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('非债券类价格偏离',
|
||||
'期初价格与上一日收盘价偏离度超阈值(默认5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 47, 'VariableName', '期初价格偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 5,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'Math.Abs(trade.SpotPrice - market.LastClosePrice) / market.LastClosePrice * 100 > 5',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则15:单一交易对手累计标的数量超阈值(审批,对手方)
|
||||
-- 条件:对手方累计标的数量(ID=32) > 10个
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('单一交易对手累计标的数量超阈值',
|
||||
'对手方累计标的数量超过阈值(默认10个)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 32, 'VariableName', '对手方累计标的数量', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 10,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '个'
|
||||
)),
|
||||
'calc.CounterpartyUnderlyingCount > 10',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则16:多头支付固定端利率偏离(审批,账户)
|
||||
-- 条件:多空方向为多头(ID=41) AND 利息端利率与FR007偏离度(ID=48) > 3%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('多头支付固定端利率偏离',
|
||||
'多头方向支付固定端场景下,利息端利率与FR007偏离度超阈值(默认3%)时触发审批',
|
||||
JSON_ARRAY(
|
||||
JSON_OBJECT(
|
||||
'VariableId', 41, 'VariableName', '多空方向为多头', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
),
|
||||
JSON_OBJECT(
|
||||
'VariableId', 48, 'VariableName', '利息端利率与FR007偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 3,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)
|
||||
),
|
||||
'calc.IsLongDirection == true && Math.Abs(calc.InterestRate - market.FR007) / market.FR007 * 100 > 3',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则17:空头利率减点借贷加权偏离(审批,账户)
|
||||
-- 条件:多空方向为空头(ID=42) AND 利息端利率与借贷加权费率偏离度(ID=49) > 2%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('空头利率减点借贷加权偏离',
|
||||
'空头方向场景下,利息端利率与借贷加权费率偏离度超阈值(默认2%)时触发审批',
|
||||
JSON_ARRAY(
|
||||
JSON_OBJECT(
|
||||
'VariableId', 42, 'VariableName', '多空方向为空头', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
),
|
||||
JSON_OBJECT(
|
||||
'VariableId', 49, 'VariableName', '利息端利率与借贷加权费率偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 2,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)
|
||||
),
|
||||
'calc.IsShortDirection == true && Math.Abs(calc.InterestRate - market.BondLendingRate) / market.BondLendingRate * 100 > 2',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则18:账户授权收支方向不匹配(禁止,账户)
|
||||
-- 条件:保证金收支方向为支付(ID=43)(实际需结合账户授权方向判断,此处简化)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('账户授权收支方向不匹配',
|
||||
'保证金收支方向与账户授权方向不匹配时禁止交易',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 43, 'VariableName', '保证金收支方向为支付', 'VariableType', 'Boolean',
|
||||
'Operator', '是', 'ThresholdType', 'fixed', 'Value', true,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', JSON_TYPE(NULL)
|
||||
)),
|
||||
'calc.IsMarginPay == true',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则19:执行价偏离超阈值(审批,账户)
|
||||
-- 条件:执行价偏离度(ID=50) > 5%
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('执行价偏离超阈值',
|
||||
'执行价与参考价格偏离度超阈值(默认5%)时触发审批',
|
||||
JSON_ARRAY(JSON_OBJECT(
|
||||
'VariableId', 50, 'VariableName', '执行价偏离度', 'VariableType', 'Numeric',
|
||||
'Operator', '>', 'ThresholdType', 'fixed', 'Value', 5,
|
||||
'ThresholdVariableId', JSON_TYPE(NULL), 'ThresholdVariableName', JSON_TYPE(NULL), 'Unit', '%'
|
||||
)),
|
||||
'Math.Abs(trade.StrikePrice - market.ReferencePrice) / market.ReferencePrice * 100 > 5',
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则20:希腊字母限额超阈值(提示,预留接口,一期不纳入)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('希腊字母限额超阈值',
|
||||
'Delta/Gamma/Vega/Theta任一超阈值时提示(预留接口,一期不纳入)',
|
||||
NULL,
|
||||
NULL,
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 规则21:接近/触发敲入敲出价(提示,预留接口,需确认具体判断逻辑)
|
||||
INSERT INTO `glms_risk_rule` (`RuleName`, `RuleText`, `ConditionJson`, `RuleExpr`, `Status`, `Version`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('接近/触发敲入敲出价',
|
||||
'标的价格接近敲入/敲出价时提示(预留接口,需确认具体判断逻辑)',
|
||||
NULL,
|
||||
NULL,
|
||||
1, 1, 0, 'SYSTEM', NOW());
|
||||
@@ -45,6 +45,20 @@ INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`
|
||||
('同一标的累计名义本金', 3, 1, '元', '≥ 0', 'SUM(该标的所有存续交易的 StockEqvNotional),含本笔', 'calc.SameUnderlyingTotalNotional', 310, 0, 'SYSTEM', NOW()),
|
||||
('同一客户累计名义本金', 3, 1, '元', '≥ 0', 'SUM(该客户所有存续交易的 StockEqvNotional),含本笔', 'calc.SameClientTotalNotional', 311, 0, 'SYSTEM', NOW()),
|
||||
('总持仓名义本金', 3, 1, '元', '≥ 0', 'SUM(所有存续交易的 StockEqvNotional)', 'calc.TotalPositionNotional', 312, 0, 'SYSTEM', NOW());
|
||||
-- 新增变量(ID 45~53):
|
||||
-- 45=期初净价偏离度 46=期初收益率偏离度 47=期初价格偏离度
|
||||
-- 48=利息端利率与FR007偏离度 49=利息端利率与借贷加权费率偏离度
|
||||
-- 50=执行价偏离度 51=执行价 52=客户品种最低保证金率 53=参考价格
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('期初净价偏离度', 3, 1, '%', '≥ 0', 'ABS(期初净价-中债估值净价)/中债估值净价*100', 'Math.Abs(swap_position.PosiNetNoFeePrice - market.CBValuationNetPrice) / market.CBValuationNetPrice * 100', 313, 0, 'SYSTEM', NOW()),
|
||||
('期初收益率偏离度', 3, 1, '%', '≥ 0', 'ABS(期初收益率-中债估值收益率)/中债估值收益率*100', 'Math.Abs(trade.InitYtm - market.CBValuationYtm) / market.CBValuationYtm * 100', 314, 0, 'SYSTEM', NOW()),
|
||||
('期初价格偏离度', 3, 1, '%', '≥ 0', 'ABS(期初价格-上一日收盘价)/上一日收盘价*100', 'Math.Abs(trade.SpotPrice - market.LastClosePrice) / market.LastClosePrice * 100', 315, 0, 'SYSTEM', NOW()),
|
||||
('利息端利率与FR007偏离度', 3, 1, '%', '≥ 0', 'ABS(利息端利率-FR007)/FR007*100', 'Math.Abs(calc.InterestRate - market.FR007) / market.FR007 * 100', 316, 0, 'SYSTEM', NOW()),
|
||||
('利息端利率与借贷加权费率偏离度', 3, 1, '%', '≥ 0', 'ABS(利息端利率-借贷加权费率)/借贷加权费率*100', 'Math.Abs(calc.InterestRate - market.BondLendingRate) / market.BondLendingRate * 100', 317, 0, 'SYSTEM', NOW()),
|
||||
('执行价偏离度', 3, 1, '%', '≥ 0', 'ABS(执行价-参考价格)/参考价格*100', 'Math.Abs(trade.StrikePrice - market.ReferencePrice) / market.ReferencePrice * 100', 318, 0, 'SYSTEM', NOW()),
|
||||
('执行价', 1, 1, '元', '≥ 0', 'trade.StrikePrice', 'trade.StrikePrice', 115, 0, 'SYSTEM', NOW()),
|
||||
('客户品种最低保证金率', 1, 1, '%', '0~100', '客户品种最低保证金率(由账户/标的配置决定)', 'config.MinMarginRate', 116, 0, 'SYSTEM', NOW()),
|
||||
('参考价格', 2, 1, '元', '≥ 0', '执行价参考价格(行情数据)', 'market.ReferencePrice', 210, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 4.4.4 布尔判断类(Category=4)
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public class QueryRiskApplicationReq : BaseSearchReq
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public RiskRuleStatus? Status { get; set; }
|
||||
public RiskControlStrategy? Strategy { get; set; }
|
||||
public string TriggerPoint { get; set; }
|
||||
|
||||
@@ -6,6 +6,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class QueryRiskVariableReq : BaseSearchReq
|
||||
{
|
||||
public RiskVariableCategory? Category { get; set; }
|
||||
public string Keyword { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public long Id { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleExpr { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public int Version { get; set; }
|
||||
public string OptName { get; set; }
|
||||
|
||||
@@ -12,6 +12,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string ScopeUnderlyingTypes { get; set; }
|
||||
public string ScopeTradeTypes { get; set; }
|
||||
public bool ScopeIsGlobal { get; set; }
|
||||
public int ExpectedVersion { get; set; }
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string RuleText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleExpr { get; set; }
|
||||
public int ExpectedVersion { get; set; }
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string Description { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public int ExpectedVersion { get; set; }
|
||||
public int Version { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
|
||||
public static RiskEngineService GetInstance() => _instance.Value;
|
||||
|
||||
private RiskEngineService() : base((OptUserInfo)null)
|
||||
private RiskEngineService() : base(OptUserInfo.SystemUser)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
public class RiskRuleService : YLBaseService
|
||||
{
|
||||
private readonly IYcLogger _logger = LogFactory.GetLogger("RiskRuleService");
|
||||
private readonly RiskEngineService _riskEngineService;
|
||||
|
||||
private HashSet<string> _variableExprCache;
|
||||
private DateTime _variableCacheUpdateTime;
|
||||
@@ -208,17 +207,14 @@ namespace YLErp.Modules.RiskEngine
|
||||
|
||||
public RiskRuleService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
_riskEngineService = RiskEngineService.GetInstance();
|
||||
}
|
||||
|
||||
public RiskRuleService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
_riskEngineService = RiskEngineService.GetInstance();
|
||||
}
|
||||
|
||||
public RiskRuleService(OptUserInfo optUser, YLContext dbContext) : base(optUser, dbContext)
|
||||
{
|
||||
_riskEngineService = RiskEngineService.GetInstance();
|
||||
}
|
||||
|
||||
#region Private Helpers
|
||||
@@ -399,7 +395,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
try
|
||||
{
|
||||
_riskEngineService.RefreshCache();
|
||||
RiskEngineService.GetInstance().RefreshCache();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -560,6 +556,8 @@ namespace YLErp.Modules.RiskEngine
|
||||
Id = r.id,
|
||||
RuleName = r.RuleName,
|
||||
RuleText = r.RuleText,
|
||||
ConditionJson = r.ConditionJson,
|
||||
RuleExpr = r.RuleExpr,
|
||||
Status = r.Status,
|
||||
Version = r.Version,
|
||||
OptName = r.OptName,
|
||||
@@ -653,7 +651,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
var rule = GetRuleOrThrow(ruleId);
|
||||
|
||||
if (rule.Version != req.ExpectedVersion)
|
||||
if (rule.Version != req.Version)
|
||||
throw new ServiceException("规则已被其他用户修改,请重新加载后再编辑");
|
||||
|
||||
ValidateRuleParams(req.RuleName, req.ConditionJson, req.RuleExpr);
|
||||
@@ -704,13 +702,11 @@ namespace YLErp.Modules.RiskEngine
|
||||
throw new ServiceException("仅已停用的规则可以启用");
|
||||
|
||||
rule.Status = RiskRuleStatus.Active;
|
||||
rule.Version = rule.Version + 1;
|
||||
rule.UpdateOptId = UserId;
|
||||
rule.UpdateOptName = UserName;
|
||||
rule.UpdateDate = DateTime.Now;
|
||||
|
||||
WriteAuditLog("RULE_ENABLE", "RULE", ruleId, rule.RuleName, "启用规则",
|
||||
snapshotData: JsonConvert.SerializeObject(new { Version = rule.Version }));
|
||||
WriteAuditLog("RULE_ENABLE", "RULE", ruleId, rule.RuleName, "启用规则");
|
||||
DbContext.SaveChanges();
|
||||
|
||||
TryRefreshCache();
|
||||
@@ -723,7 +719,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
throw new ServiceException("仅已生效的规则可以停用");
|
||||
|
||||
rule.Status = RiskRuleStatus.Disabled;
|
||||
rule.Version = rule.Version + 1;
|
||||
rule.UpdateOptId = UserId;
|
||||
rule.UpdateOptName = UserName;
|
||||
rule.UpdateDate = DateTime.Now;
|
||||
@@ -872,6 +867,14 @@ namespace YLErp.Modules.RiskEngine
|
||||
query = query.Where(a => a.TriggerPoints.Contains(req.TriggerPoint));
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.RuleName))
|
||||
{
|
||||
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)));
|
||||
}
|
||||
|
||||
var pagedApps = query.OrderByDescending(a => a.UpdateDate)
|
||||
.Select(a => new
|
||||
{
|
||||
@@ -937,13 +940,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
};
|
||||
}).ToList();
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.Keyword))
|
||||
{
|
||||
resultList = resultList
|
||||
.Where(a => a.RuleNames.Contains(req.Keyword))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return new SearchListResult<RiskApplicationListItem>
|
||||
{
|
||||
rows = resultList,
|
||||
@@ -1050,7 +1046,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
var app = GetApplicationOrThrow(applicationId);
|
||||
|
||||
if (app.Version != req.ExpectedVersion)
|
||||
if (app.Version != req.Version)
|
||||
throw new ServiceException("应用配置已被其他用户修改,请重新加载后再编辑");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.RuleIds))
|
||||
@@ -1115,7 +1111,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
ValidateRuleIdsActive(app.RuleIds);
|
||||
|
||||
app.Status = RiskRuleStatus.Active;
|
||||
app.Version = app.Version + 1;
|
||||
app.UpdateOptId = UserId;
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
@@ -1133,7 +1128,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
throw new ServiceException("仅已生效的应用配置可以停用");
|
||||
|
||||
app.Status = RiskRuleStatus.Disabled;
|
||||
app.Version = app.Version + 1;
|
||||
app.UpdateOptId = UserId;
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
@@ -1161,7 +1155,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
foreach (var app in apps)
|
||||
{
|
||||
app.Status = RiskRuleStatus.Active;
|
||||
app.Version = app.Version + 1;
|
||||
app.UpdateOptId = UserId;
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
@@ -1192,7 +1185,6 @@ namespace YLErp.Modules.RiskEngine
|
||||
foreach (var app in apps)
|
||||
{
|
||||
app.Status = RiskRuleStatus.Disabled;
|
||||
app.Version = app.Version + 1;
|
||||
app.UpdateOptId = UserId;
|
||||
app.UpdateOptName = UserName;
|
||||
app.UpdateDate = DateTime.Now;
|
||||
@@ -1224,9 +1216,9 @@ namespace YLErp.Modules.RiskEngine
|
||||
query = query.Where(v => v.Category == req.Category.Value);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(req.Keyword))
|
||||
if (!string.IsNullOrWhiteSpace(req.VariableName))
|
||||
{
|
||||
query = query.Where(v => v.VariableName.Contains(req.Keyword));
|
||||
query = query.Where(v => v.VariableName.Contains(req.VariableName));
|
||||
}
|
||||
|
||||
var result = query.OrderBy(v => v.SortOrder).ThenBy(v => v.VariableName)
|
||||
@@ -1334,7 +1326,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
var variable = GetVariableOrThrow(variableId);
|
||||
|
||||
if (variable.Version != req.ExpectedVersion)
|
||||
if (variable.Version != req.Version)
|
||||
throw new ServiceException("变量已被其他用户修改,请重新加载后再编辑");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(req.VariableName))
|
||||
|
||||
Reference in New Issue
Block a user