From c2fc699e5757202a0b9abd310e2ceb350d2f153c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=B9=E5=B3=B0?= Date: Wed, 24 Jun 2026 18:23:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(risk-engine):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E9=A3=8E=E6=8E=A7=E8=A7=84=E5=88=99=E7=A7=8D=E5=AD=90=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E4=B8=8E=20CRUD=20=E6=8E=A5=E5=8F=A3=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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() 直接调用 --- .../DbUpdate/Ver-5.6.0/seed_applications.sql | 135 ++++++++ .../DbUpdate/Ver-5.6.0/seed_rules.sql | 306 ++++++++++++++++++ .../DbUpdate/Ver-5.6.0/seed_variables.sql | 14 + .../RiskEngine/Dto/QueryRiskApplicationReq.cs | 2 +- .../RiskEngine/Dto/QueryRiskVariableReq.cs | 2 +- .../RiskEngine/Dto/RiskRuleListItem.cs | 2 + .../Dto/UpdateRiskApplicationReq.cs | 2 +- .../RiskEngine/Dto/UpdateRiskRuleReq.cs | 2 +- .../RiskEngine/Dto/UpdateRiskVariableReq.cs | 2 +- .../Modules/RiskEngine/RiskEngineService.cs | 2 +- .../Modules/RiskEngine/RiskRuleService.cs | 42 +-- 11 files changed, 480 insertions(+), 31 deletions(-) create mode 100644 Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_applications.sql create mode 100644 Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_rules.sql diff --git a/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_applications.sql b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_applications.sql new file mode 100644 index 00000000..8c3cf942 --- /dev/null +++ b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_applications.sql @@ -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 = '接近/触发敲入敲出价'; diff --git a/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_rules.sql b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_rules.sql new file mode 100644 index 00000000..33b72018 --- /dev/null +++ b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_rules.sql @@ -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()); diff --git a/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_variables.sql b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_variables.sql index 050d5470..934a3a27 100644 --- a/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_variables.sql +++ b/Framework/YLErp.Resources/DbUpdate/Ver-5.6.0/seed_variables.sql @@ -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 diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs index f195ee7c..bd494ed8 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskApplicationReq.cs @@ -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; } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs index cc9dc45a..639d9b3d 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/QueryRiskVariableReq.cs @@ -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; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs index ec0c3610..988f55c4 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/RiskRuleListItem.cs @@ -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; } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs index 73cafe4f..b9af55a9 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskApplicationReq.cs @@ -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; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs index 466286c8..85521bac 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskRuleReq.cs @@ -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; } } } diff --git a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs index 1c19502b..2990b7c1 100644 --- a/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs +++ b/YLErpDAL/Modules/RiskEngine/Dto/UpdateRiskVariableReq.cs @@ -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; } } } diff --git a/YLErpDAL/Modules/RiskEngine/RiskEngineService.cs b/YLErpDAL/Modules/RiskEngine/RiskEngineService.cs index 6cf815a3..38dca7dc 100644 --- a/YLErpDAL/Modules/RiskEngine/RiskEngineService.cs +++ b/YLErpDAL/Modules/RiskEngine/RiskEngineService.cs @@ -173,7 +173,7 @@ namespace YLErp.Modules.RiskEngine public static RiskEngineService GetInstance() => _instance.Value; - private RiskEngineService() : base((OptUserInfo)null) + private RiskEngineService() : base(OptUserInfo.SystemUser) { } diff --git a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs index e12cdf1d..58c9f5e5 100644 --- a/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs +++ b/YLErpDAL/Modules/RiskEngine/RiskRuleService.cs @@ -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 _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 { 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))