feat: 规则双模式公式表达式(RuleExpr)& 字段精简重构
- 新增 RuleExpr 字段,支持结构化拼接和自由文本两种模式,二选一互斥 - 删除 RuleCode/FormulaText/ApplicationCode/SourceExpression/IsImplemented/VariableCode/TargetCode - 重命名 FormulaJson→ConditionJson, FormulaExpr→RuleExpr, ImplementationScript→VariableExpr, RuleDescription→RuleText - RuleId(bigint)→RuleIds(varchar) 多规则支持 - FormulaCondition: variableCode(string)→variableId(long), thresholdVariableCode→thresholdVariableId - 新增 44 条变量池 seed 数据 - 设计文档同步更新
This commit is contained in:
@@ -5,11 +5,10 @@ namespace YLErp.DBModels
|
||||
[Table("glms_risk_rule")]
|
||||
public class glms_risk_rule : DBModelWithOperator
|
||||
{
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string RuleDescription { get; set; }
|
||||
public string FormulaJson { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleExpr { get; set; }
|
||||
public RiskRuleStatus Status { get; set; } = RiskRuleStatus.Active;
|
||||
public int Version { get; set; } = 1;
|
||||
public int? UpdateOptId { get; set; }
|
||||
|
||||
@@ -5,8 +5,7 @@ namespace YLErp.DBModels
|
||||
[Table("glms_risk_rule_application")]
|
||||
public class glms_risk_rule_application : DBModelWithOperator
|
||||
{
|
||||
public string ApplicationCode { get; set; }
|
||||
public long RuleId { get; set; }
|
||||
public string RuleIds { get; set; }
|
||||
public RiskRuleStatus Status { get; set; } = RiskRuleStatus.Active;
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace YLErp.DBModels
|
||||
public string TargetType { get; set; }
|
||||
public long TargetId { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
public string TargetCode { get; set; }
|
||||
public string OperationDetail { get; set; }
|
||||
public string Result { get; set; }
|
||||
public string SnapshotData { get; set; }
|
||||
|
||||
@@ -5,16 +5,13 @@ namespace YLErp.DBModels
|
||||
[Table("glms_risk_variable")]
|
||||
public class glms_risk_variable : DBModelWithOperator
|
||||
{
|
||||
public string VariableCode { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public RiskVariableCategory Category { get; set; }
|
||||
public RiskVariableDataType DataType { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public string ValueDomain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string ImplementationScript { get; set; }
|
||||
public string SourceExpression { get; set; }
|
||||
public bool IsImplemented { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int Version { get; set; } = 1;
|
||||
public int SortOrder { get; set; }
|
||||
public int? UpdateOptId { get; set; }
|
||||
|
||||
@@ -2,11 +2,10 @@ SET FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
CREATE TABLE `glms_risk_rule` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键Id',
|
||||
`RuleCode` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '规则编码(RISK-YYYYMMDD-NNNN)',
|
||||
`RuleName` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '规则名称',
|
||||
`RuleDescription` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '规则描述',
|
||||
`FormulaJson` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '公式JSON表达式',
|
||||
`FormulaText` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '公式可读文本',
|
||||
`RuleText` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '规则文本',
|
||||
`ConditionJson` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '条件JSON(结构化模式, FormulaCondition数组)',
|
||||
`RuleExpr` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '规则表达式(自由文本模式, 类C#表达式)',
|
||||
`Status` tinyint NOT NULL DEFAULT 1 COMMENT '状态: 1=Active, 2=Disabled, 3=Deleted',
|
||||
`Version` int NOT NULL DEFAULT 1 COMMENT '版本号(乐观锁)',
|
||||
`OptId` int NULL DEFAULT NULL COMMENT '创建人Id',
|
||||
@@ -16,14 +15,12 @@ CREATE TABLE `glms_risk_rule` (
|
||||
`UpdateOptName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最后修改人名称',
|
||||
`UpdateDate` datetime NULL DEFAULT NULL COMMENT '最后修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_rule_code`(`RuleCode` ASC) USING BTREE,
|
||||
INDEX `idx_status`(`Status` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '风控规则定义表' ROW_FORMAT = Dynamic;
|
||||
|
||||
CREATE TABLE `glms_risk_rule_application` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键Id',
|
||||
`ApplicationCode` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '应用编码(APP-YYYYMMDD-NNNN)',
|
||||
`RuleId` bigint NOT NULL COMMENT '关联规则Id',
|
||||
`RuleIds` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '关联规则Id列表(逗号分隔)',
|
||||
`Status` tinyint NOT NULL DEFAULT 1 COMMENT '状态: 1=Active, 2=Disabled, 3=Deleted',
|
||||
`ControlStrategy` tinyint NOT NULL COMMENT '控制策略: 1=Block, 2=Approval, 3=Warning',
|
||||
`TriggerPoints` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '触发时点(逗号分隔)',
|
||||
@@ -40,8 +37,6 @@ CREATE TABLE `glms_risk_rule_application` (
|
||||
`UpdateOptName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最后修改人名称',
|
||||
`UpdateDate` datetime NULL DEFAULT NULL COMMENT '最后修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_application_code`(`ApplicationCode` ASC) USING BTREE,
|
||||
INDEX `idx_rule_id`(`RuleId` ASC) USING BTREE,
|
||||
INDEX `idx_status`(`Status` ASC) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '风控规则应用配置表' ROW_FORMAT = Dynamic;
|
||||
|
||||
@@ -51,7 +46,6 @@ CREATE TABLE `glms_risk_rule_audit_log` (
|
||||
`TargetType` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '目标类型(RULE/APPLICATION/VARIABLE)',
|
||||
`TargetId` bigint NOT NULL COMMENT '目标记录Id',
|
||||
`TargetName` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '目标名称',
|
||||
`TargetCode` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '目标编码',
|
||||
`OperationDetail` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '操作详情',
|
||||
`Result` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '操作结果',
|
||||
`SnapshotData` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '快照数据(JSON)',
|
||||
@@ -67,16 +61,13 @@ CREATE TABLE `glms_risk_rule_audit_log` (
|
||||
|
||||
CREATE TABLE `glms_risk_variable` (
|
||||
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键Id',
|
||||
`VariableCode` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '变量编码',
|
||||
`VariableName` varchar(200) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '变量名称',
|
||||
`Category` tinyint NOT NULL COMMENT '分类: 1=BookingElement, 2=MarketData, 3=SystemCalc, 4=BooleanCheck',
|
||||
`DataType` tinyint NOT NULL COMMENT '数据类型: 1=Numeric, 2=Date, 3=Boolean',
|
||||
`Unit` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '单位',
|
||||
`ValueDomain` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '值域描述',
|
||||
`Description` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '描述',
|
||||
`ImplementationScript` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '实现脚本(C#表达式)',
|
||||
`SourceExpression` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '来源表达式',
|
||||
`IsImplemented` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否已实现: 0=否, 1=是',
|
||||
`VariableExpr` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT '变量表达式(C#表达式)',
|
||||
`Version` int NOT NULL DEFAULT 1 COMMENT '版本号(乐观锁)',
|
||||
`SortOrder` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||
`OptId` int NULL DEFAULT NULL COMMENT '创建人Id',
|
||||
@@ -85,8 +76,7 @@ CREATE TABLE `glms_risk_variable` (
|
||||
`UpdateOptId` int NULL DEFAULT NULL COMMENT '最后修改人Id',
|
||||
`UpdateOptName` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '最后修改人名称',
|
||||
`UpdateDate` datetime NULL DEFAULT NULL COMMENT '最后修改时间',
|
||||
PRIMARY KEY (`id`) USING BTREE,
|
||||
UNIQUE INDEX `uk_variable_code`(`VariableCode` ASC) USING BTREE
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '风控变量池定义表' ROW_FORMAT = Dynamic;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
-- ============================================================
|
||||
-- 变量池初始数据(对应设计文档 §4.4 变量池完整清单)
|
||||
-- ============================================================
|
||||
|
||||
-- 4.4.1 簿记要素类(Category=1)
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('合约名义本金', 1, 1, '元', '≥ 0', 'trade.StockEqvNotional 或 swap_position.PosiNotionalValue', 'trade.StockEqvNotional', 101, 0, 'SYSTEM', NOW()),
|
||||
('合约起息日', 1, 2, NULL, NULL, 'trade.StartDate 或 swap_position.PosiStartDate', 'trade.StartDate', 102, 0, 'SYSTEM', NOW()),
|
||||
('合约到期日', 1, 2, NULL, NULL, 'trade.ExerciseDate 或 swap_position.PosiMatuirityDate', 'trade.ExerciseDate', 103, 0, 'SYSTEM', NOW()),
|
||||
('合约平仓日', 1, 2, NULL, NULL, 'trade.UnWindDate', 'trade.UnWindDate', 104, 0, 'SYSTEM', NOW()),
|
||||
('合约支付日', 1, 2, NULL, NULL, 'trade.SettlementDate', 'trade.SettlementDate', 105, 0, 'SYSTEM', NOW()),
|
||||
('期初净价', 1, 1, '元', '≥ 0', 'swap_position.PosiNetNoFeePrice(债券 TRS)', 'swap_position.PosiNetNoFeePrice', 106, 0, 'SYSTEM', NOW()),
|
||||
('期初全价', 1, 1, '元', '≥ 0', 'swap_position.PosiNetFeePrice(债券 TRS)/ trade.SpotPrice(其他)', 'swap_position.PosiNetFeePrice', 107, 0, 'SYSTEM', NOW()),
|
||||
('期初收益率', 1, 1, '%', NULL, 'trade.InitYtm 或 swap_position.InitYtm', 'trade.InitYtm', 108, 0, 'SYSTEM', NOW()),
|
||||
('期初价格', 1, 1, '元', '≥ 0', 'trade.SpotPrice(非债券类)', 'trade.SpotPrice', 109, 0, 'SYSTEM', NOW()),
|
||||
('期末全价', 1, 1, '元', '≥ 0', 'eod_swap_position.UnderlyingPrice(债券 TRS)', 'eod_swap_position.UnderlyingPrice', 110, 0, 'SYSTEM', NOW()),
|
||||
('期末价格', 1, 1, '元', '≥ 0', 'trade.FinalPrice', 'trade.FinalPrice', 111, 0, 'SYSTEM', NOW()),
|
||||
('保证金利率', 1, 1, '%', NULL, 'client_marginrate.InitMarginRebateRate', 'client_marginrate.InitMarginRebateRate', 112, 0, 'SYSTEM', NOW()),
|
||||
('保证金比例', 1, 1, '%', '0~100', 'trade.MarginRate', 'trade.MarginRate', 113, 0, 'SYSTEM', NOW()),
|
||||
('客户授信额度', 1, 1, '元', '≥ 0', 'credit.Credit', 'credit.Credit', 114, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 4.4.2 行情类(Category=2,统一取上一交易日收盘价)
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('上一收盘日中债估值净价', 2, 1, '元', '≥ 0', '资讯数据', 'market.CBValuationNetPrice', 201, 0, 'SYSTEM', NOW()),
|
||||
('上一收盘日中债估值全价', 2, 1, '元', '≥ 0', '资讯数据', 'market.CBValuationFullPrice', 202, 0, 'SYSTEM', NOW()),
|
||||
('上一收盘日中债估值收益率', 2, 1, '%', NULL, '资讯数据', 'market.CBValuationYtm', 203, 0, 'SYSTEM', NOW()),
|
||||
('上一日收盘价', 2, 1, '元', '≥ 0', '行情数据,按标的区分', 'market.LastClosePrice', 204, 0, 'SYSTEM', NOW()),
|
||||
('借贷加权费率', 2, 1, '%', NULL, 'CMDM 标的债券借贷费率行情表', 'market.BondLendingRate', 205, 0, 'SYSTEM', NOW()),
|
||||
('FR007', 2, 1, '%', NULL, '上一交易日收盘价', 'market.FR007', 206, 0, 'SYSTEM', NOW()),
|
||||
('当前日期', 2, 2, NULL, NULL, 'DateTime.Today', 'sys.CurrentDate', 207, 0, 'SYSTEM', NOW()),
|
||||
('挂钩标的到期日', 2, 2, NULL, NULL, '资讯数据', 'market.UnderlyingMaturityDate', 208, 0, 'SYSTEM', NOW()),
|
||||
('标的发行余额', 2, 1, '元', '≥ 0', '资讯数据', 'market.UnderlyingIssueBalance', 209, 0, 'SYSTEM', NOW());
|
||||
|
||||
-- 4.4.3 系统计算值类(Category=3)
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('挂钩标的集中度', 3, 1, '%', '0~100', '同一标的存续交易总名义本金 ÷ 标的发行余额 × 100', 'calc.UnderlyingConcentration', 301, 0, 'SYSTEM', NOW()),
|
||||
('授信占用率', 3, 1, '%', '0~100', '(已占用授信 + 本笔授信占用) ÷ 授信总额 × 100', 'calc.CreditUsageRate', 302, 0, 'SYSTEM', NOW()),
|
||||
('合约期限', 3, 1, '天', '≥ 0', '(ExerciseDate - StartDate).Days', 'calc.MaturityDays', 303, 0, 'SYSTEM', NOW()),
|
||||
('Delta', 3, 1, NULL, NULL, 'realtime_trade_risk.Delta(预留接口,一期不纳入)', 'realtime_trade_risk.Delta', 304, 0, 'SYSTEM', NOW()),
|
||||
('Gamma', 3, 1, NULL, NULL, 'realtime_trade_risk.Gamma(预留接口,一期不纳入)', 'realtime_trade_risk.Gamma', 305, 0, 'SYSTEM', NOW()),
|
||||
('Vega', 3, 1, NULL, NULL, 'realtime_trade_risk.Vega(预留接口,一期不纳入)', 'realtime_trade_risk.Vega', 306, 0, 'SYSTEM', NOW()),
|
||||
('Theta', 3, 1, NULL, NULL, 'realtime_trade_risk.Theta(预留接口,一期不纳入)', 'realtime_trade_risk.Theta', 307, 0, 'SYSTEM', NOW()),
|
||||
('利息端利率', 3, 1, '%', NULL, '固定利率 或 FR007 ± 加点', 'calc.InterestRate', 308, 0, 'SYSTEM', NOW()),
|
||||
('对手方累计标的数量', 3, 1, '个', '≥ 0', 'COUNT(DISTINCT UnderlyingId) 该对手方所有存续交易,含本笔', 'calc.CounterpartyUnderlyingCount', 309, 0, 'SYSTEM', NOW()),
|
||||
('同一标的累计名义本金', 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());
|
||||
|
||||
-- 4.4.4 布尔判断类(Category=4)
|
||||
INSERT INTO `glms_risk_variable` (`VariableName`, `Category`, `DataType`, `Unit`, `ValueDomain`, `Description`, `VariableExpr`, `SortOrder`, `OptId`, `OptName`, `OptDate`) VALUES
|
||||
('到期日是否银行间交易日', 4, 3, NULL, NULL, '查询银行间交易日历', 'calc.IsExerciseDateTradingDay', 401, 0, 'SYSTEM', NOW()),
|
||||
('平仓日是否银行间交易日', 4, 3, NULL, NULL, '查询银行间交易日历', 'calc.IsUnwindDateTradingDay', 402, 0, 'SYSTEM', NOW()),
|
||||
('支付日是否银行间交易日', 4, 3, NULL, NULL, '查询银行间交易日历', 'calc.IsSettlementDateTradingDay', 403, 0, 'SYSTEM', NOW()),
|
||||
('利息端/浮动端方向是否同向', 4, 3, NULL, NULL, '利息端"收取"↔浮动端"多头",利息端"支付"↔浮动端"空头"', 'calc.IsInterestFloatSameDirection', 404, 0, 'SYSTEM', NOW()),
|
||||
('关键业务要素是否一致', 4, 3, NULL, NULL, '交易确认书 vs 簿记要素(大模型方案)', 'calc.IsKeyElementsConsistent', 405, 0, 'SYSTEM', NOW()),
|
||||
('多空方向为多头', 4, 3, NULL, NULL, 'trade.BuySell == "买入" 或浮动端为多头', 'calc.IsLongDirection', 406, 0, 'SYSTEM', NOW()),
|
||||
('多空方向为空头', 4, 3, NULL, NULL, '与多头互斥', 'calc.IsShortDirection', 407, 0, 'SYSTEM', NOW()),
|
||||
('保证金收支方向为支付', 4, 3, NULL, NULL, '保证金方向为支付', 'calc.IsMarginPay', 408, 0, 'SYSTEM', NOW()),
|
||||
('保证金收支方向为收取', 4, 3, NULL, NULL, '与支付互斥', 'calc.IsMarginReceive', 409, 0, 'SYSTEM', NOW());
|
||||
@@ -4,7 +4,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public class CreateRiskApplicationReq
|
||||
{
|
||||
public long RuleId { get; set; }
|
||||
public string RuleIds { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
public string ScopeAssetBookIds { get; set; }
|
||||
|
||||
@@ -3,8 +3,8 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class CreateRiskRuleReq
|
||||
{
|
||||
public string RuleName { get; set; }
|
||||
public string RuleDescription { get; set; }
|
||||
public string FormulaJson { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleExpr { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,13 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public class CreateRiskVariableReq
|
||||
{
|
||||
public string VariableCode { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public RiskVariableCategory Category { get; set; }
|
||||
public RiskVariableDataType DataType { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public string ValueDomain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string ImplementationScript { get; set; }
|
||||
public string SourceExpression { get; set; }
|
||||
public bool IsImplemented { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,13 +2,13 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public class FormulaCondition
|
||||
{
|
||||
public string VariableCode { get; set; }
|
||||
public long VariableId { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public string VariableType { get; set; }
|
||||
public string Operator { get; set; }
|
||||
public string ThresholdType { get; set; }
|
||||
public object Value { get; set; }
|
||||
public string ThresholdVariableCode { get; set; }
|
||||
public long? ThresholdVariableId { get; set; }
|
||||
public string ThresholdVariableName { get; set; }
|
||||
public string Unit { get; set; }
|
||||
}
|
||||
|
||||
@@ -7,6 +7,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public string Keyword { get; set; }
|
||||
public RiskRuleStatus? Status { get; set; }
|
||||
public string VariableCode { get; set; }
|
||||
public long? VariableId { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,10 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskApplicationDetail
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string ApplicationCode { get; set; }
|
||||
public long RuleId { get; set; }
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleIds { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string FormulaJson { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleNames { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
|
||||
@@ -6,11 +6,9 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskApplicationListItem
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string ApplicationCode { get; set; }
|
||||
public long RuleId { get; set; }
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleIds { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleNames { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string TargetType { get; set; }
|
||||
public long TargetId { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
public string TargetCode { get; set; }
|
||||
public string OperationDetail { get; set; }
|
||||
public string Result { get; set; }
|
||||
public string SnapshotData { get; set; }
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string TargetType { get; set; }
|
||||
public long TargetId { get; set; }
|
||||
public string TargetName { get; set; }
|
||||
public string TargetCode { get; set; }
|
||||
public string OperationDetail { get; set; }
|
||||
public string Result { get; set; }
|
||||
public string OptName { get; set; }
|
||||
|
||||
@@ -5,7 +5,6 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskRuleApplicationSummary
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string ApplicationCode { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
|
||||
@@ -7,11 +7,10 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskRuleDetail
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string RuleDescription { get; set; }
|
||||
public string FormulaJson { get; set; }
|
||||
public string FormulaText { 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; }
|
||||
|
||||
@@ -6,10 +6,8 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskRuleListItem
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string RuleDescription { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public RiskRuleStatus Status { get; set; }
|
||||
public int Version { get; set; }
|
||||
public string OptName { get; set; }
|
||||
|
||||
@@ -6,16 +6,13 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskVariableDetail
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string VariableCode { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public RiskVariableCategory Category { get; set; }
|
||||
public RiskVariableDataType DataType { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public string ValueDomain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string ImplementationScript { get; set; }
|
||||
public string SourceExpression { get; set; }
|
||||
public bool IsImplemented { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int Version { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public string OptName { get; set; }
|
||||
|
||||
@@ -5,14 +5,13 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskVariableListItem
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string VariableCode { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public RiskVariableCategory Category { get; set; }
|
||||
public RiskVariableDataType DataType { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public string ValueDomain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool IsImplemented { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int Version { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class RiskVariableSimpleItem
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string VariableCode { get; set; }
|
||||
public string VariableName { get; set; }
|
||||
public RiskVariableCategory Category { get; set; }
|
||||
public RiskVariableDataType DataType { get; set; }
|
||||
public string Unit { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
{
|
||||
public class UpdateRiskApplicationReq
|
||||
{
|
||||
public string RuleIds { get; set; }
|
||||
public RiskControlStrategy ControlStrategy { get; set; }
|
||||
public string TriggerPoints { get; set; }
|
||||
public string ScopeAssetBookIds { get; set; }
|
||||
|
||||
@@ -3,9 +3,9 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public class UpdateRiskRuleReq
|
||||
{
|
||||
public string RuleName { get; set; }
|
||||
public string RuleDescription { get; set; }
|
||||
public string FormulaJson { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
public string RuleExpr { get; set; }
|
||||
public int ExpectedVersion { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,7 @@ namespace YLErp.Modules.RiskEngine.Dto
|
||||
public string Unit { get; set; }
|
||||
public string ValueDomain { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string ImplementationScript { get; set; }
|
||||
public string SourceExpression { get; set; }
|
||||
public bool IsImplemented { get; set; }
|
||||
public string VariableExpr { get; set; }
|
||||
public int SortOrder { get; set; }
|
||||
public int ExpectedVersion { get; set; }
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@ using YLErp.Model;
|
||||
- RiskRule(风控规则):单条规则包含完整的公式定义 + 校验策略 + 触发时点 + 适用范围。
|
||||
不需要 "一个 Rule 对应多个 Application" 的复杂关系。
|
||||
- Content:用户输入的规则内容字符串,如"名义本金>1亿"
|
||||
- ConditionJson:条件JSON(结构化模式),如 {"conditions":[{"variableId":1,"operator":">","value":100000000}]}
|
||||
- RuleExpr:规则表达式(自由文本模式,类C#表达式)
|
||||
- 规则编译:在规则定义时(创建/加载/缓存刷新时)调用 RuleCompiler.Compile(rule),
|
||||
将 Content 解析并编译为 Func<RiskContext, bool> 委托,写入 rule.CompiledScript。
|
||||
将 ConditionJson/RuleExpr 解析并编译为 Func<RiskContext, bool> 委托,写入 rule.CompiledScript。
|
||||
判风控时直接执行委托,零解析开销。
|
||||
- RiskContext:一次风控检查的数据上下文(DataMap 机制)
|
||||
- RiskResult:风控检查结果(Passed / Blocked / NeedApproval / Warnings / TriggeredRules)
|
||||
@@ -46,7 +48,7 @@ using YLErp.Model;
|
||||
|
||||
与旧设计文档的差异:
|
||||
- 删除 RiskRuleApplication 模型,将策略/时点/范围合并到 RiskRule 中
|
||||
- 删除 FormulaJson 实时解析,改为 Content → 表达式树编译
|
||||
- 删除 FormulaJson 实时解析,改为 ConditionJson/RuleExpr → 表达式树编译
|
||||
- 规则编译跟随规则生命周期(创建/加载时),判风控时零解析
|
||||
|
||||
【架构设计】
|
||||
@@ -88,7 +90,7 @@ using YLErp.Model;
|
||||
- RiskRule.cs:合并模型(公式 + 策略 + 时点 + 范围 + CompiledScript)
|
||||
- RiskContext.cs:风控上下文(TradeId, TriggerPoint, DataMap)
|
||||
- RiskResult.cs:风控结果(Passed, Blocked, NeedApproval, Warnings, TriggeredRules)
|
||||
- RiskFormula.cs:FormulaJson 反序列化模型(辅助)
|
||||
- RiskFormula.cs:ConditionJson 反序列化模型(辅助)
|
||||
3. RuleCompiler.cs:
|
||||
- ParseContent:解析 Content 字符串(支持 > < >= <= = != ≠)
|
||||
- ParseValue:解析数值(支持 万/亿/千/百分比)
|
||||
@@ -233,7 +235,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
// 确保规则已编译
|
||||
if (rule.CompiledScript == null)
|
||||
{
|
||||
_logger.Info($"[风控引擎] 规则未编译,执行编译 - RuleCode: {rule.RuleCode}");
|
||||
_logger.Info($"[风控引擎] 规则未编译,执行编译 - RuleId: {rule.Id}");
|
||||
RuleCompiler.Compile(rule);
|
||||
}
|
||||
|
||||
@@ -242,19 +244,19 @@ namespace YLErp.Modules.RiskEngine
|
||||
try
|
||||
{
|
||||
triggered = rule.CompiledScript(context);
|
||||
_logger.Info($"[风控引擎] 规则执行 - RuleCode: {rule.RuleCode}, Triggered: {triggered}");
|
||||
_logger.Info($"[风控引擎] 规则执行 - RuleId: {rule.Id}, Triggered: {triggered}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Info($"[风控引擎] 规则执行异常 - RuleCode: {rule.RuleCode}, Error: {ex.Message}");
|
||||
_logger.Info($"[风控引擎] 规则执行异常 - RuleId: {rule.Id}, Error: {ex.Message}");
|
||||
result.HasError = true;
|
||||
result.ErrorMessage += $"规则[{rule.RuleCode}]执行异常:{ex.Message};";
|
||||
result.ErrorMessage += $"规则[{rule.Id}]执行异常:{ex.Message};";
|
||||
continue;
|
||||
}
|
||||
|
||||
if (triggered)
|
||||
{
|
||||
_logger.Info($"[风控引擎] 规则触发 - RuleCode: {rule.RuleCode}, Strategy: {rule.ControlStrategy}");
|
||||
_logger.Info($"[风控引擎] 规则触发 - RuleId: {rule.Id}, Strategy: {rule.ControlStrategy}");
|
||||
|
||||
// 按 ControlStrategy 生成结果
|
||||
switch (rule.ControlStrategy)
|
||||
@@ -264,10 +266,9 @@ namespace YLErp.Modules.RiskEngine
|
||||
result.Passed = false;
|
||||
result.TriggeredRules.Add(new TriggeredRuleInfo
|
||||
{
|
||||
RuleCode = rule.RuleCode,
|
||||
RuleName = rule.RuleName,
|
||||
ControlStrategy = "禁止",
|
||||
FormulaText = rule.FormulaText,
|
||||
RuleText = rule.RuleText,
|
||||
Message = $"规则[{rule.RuleName}]触发:禁止"
|
||||
});
|
||||
break;
|
||||
@@ -277,16 +278,15 @@ namespace YLErp.Modules.RiskEngine
|
||||
result.Passed = false;
|
||||
result.TriggeredRules.Add(new TriggeredRuleInfo
|
||||
{
|
||||
RuleCode = rule.RuleCode,
|
||||
RuleName = rule.RuleName,
|
||||
ControlStrategy = "审批",
|
||||
FormulaText = rule.FormulaText,
|
||||
RuleText = rule.RuleText,
|
||||
Message = $"规则[{rule.RuleName}]触发:需审批"
|
||||
});
|
||||
break;
|
||||
|
||||
case 3: // 提示
|
||||
result.Warnings.Add($"规则[{rule.RuleName}]触发:提示 - {rule.FormulaText}");
|
||||
result.Warnings.Add($"规则[{rule.RuleName}]触发:提示 - {rule.RuleText}");
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -315,7 +315,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
RuleCode = "ENGINE_ERROR",
|
||||
RuleName = "风控引擎执行异常",
|
||||
ControlStrategy = "审批",
|
||||
FormulaText = ex.Message,
|
||||
RuleText = ex.Message,
|
||||
Message = $"风控引擎异常:{ex.Message},需审批通过"
|
||||
});
|
||||
_logger.Error($"[风控引擎] EvaluateRisk 异常 - TradeId: {context?.TradeId}, Error: {ex.Message}");
|
||||
@@ -334,10 +334,9 @@ namespace YLErp.Modules.RiskEngine
|
||||
var rule = new RiskRule
|
||||
{
|
||||
Id = 103,
|
||||
RuleCode = "RISK-20260622-0003",
|
||||
RuleName = "测试规则:名义本金超过1亿且保证金比例超过50%禁止",
|
||||
FormulaText = "名义本金>1亿, 保证金比例>50%", // 逗号分隔,解析时自动转为 AND
|
||||
FormulaJson = "{ \"conditions\": [{\"variableCode\":\"trade.StockEqvNotional\",\"operator\":\">\",\"value\":100000000},{\"variableCode\":\"trade.MarginRate\",\"operator\":\">\",\"value\":0.5}] }",
|
||||
RuleText = "名义本金>1亿, 保证金比例>50%",
|
||||
ConditionJson = "{ \"conditions\": [{\"variableId\":1,\"operator\":\">\",\"value\":100000000},{\"variableId\":2,\"operator\":\">\",\"value\":0.5}] }",
|
||||
Status = 1, // Active
|
||||
ControlStrategy = 1, // 禁止
|
||||
TriggerPoints = "BOOK_CONFIRM",
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string ControlStrategy { get; set; }
|
||||
public string FormulaText { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,22 +14,21 @@ namespace YLErp.Modules.RiskEngine
|
||||
{
|
||||
// === 基础信息 ===
|
||||
public int Id { get; set; }
|
||||
public string RuleCode { get; set; }
|
||||
public string RuleName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string RuleText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 【核心】用户输入的规则内容字符串,如"名义本金>1亿"
|
||||
/// 在规则创建/加载时由 RuleCompiler 解析并编译为 CompiledScript
|
||||
/// </summary>
|
||||
public string FormulaText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 【核心】公式 JSON(条件列表的结构化存储),如
|
||||
/// {"conditions":[{"variableCode":"trade.StockEqvNotional","operator":">","value":100000000}]}
|
||||
/// 【核心】条件JSON(结构化模式的条件列表存储),如
|
||||
/// {"conditions":[{"variableId":1,"operator":">","value":100000000}]}
|
||||
/// 由 RuleCompiler 解析并编译为 CompiledScript
|
||||
/// </summary>
|
||||
public string FormulaJson { get; set; }
|
||||
public string ConditionJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 【核心】规则表达式(自由文本模式,类C#表达式)
|
||||
/// 由 RuleCompiler 编译为 CompiledScript
|
||||
/// </summary>
|
||||
public string RuleExpr { get; set; }
|
||||
|
||||
// === 校验策略(原 Application.ControlStrategy)===
|
||||
/// <summary>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,7 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// - 可调试:生成的脚本代码可直接阅读和理解
|
||||
///
|
||||
/// 示例:
|
||||
/// FormulaJson: { "conditions": [{"variableCode":"trade.StockEqvNotional","operator":">","value":100000000}] }
|
||||
/// ConditionJson: { "conditions": [{"variableId":1,"operator":">","value":100000000}] }
|
||||
/// 生成脚本:Convert.ToDecimal(((YLErp.DBModels.trade)DataMap["trade"]).StockEqvNotional) > 100000000m
|
||||
/// 编译结果:Func<RiskContext, bool>(内部通过 Roslyn 编译缓存)
|
||||
/// </summary>
|
||||
@@ -62,13 +62,13 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// </summary>
|
||||
public static void Compile(this RiskRule rule)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rule.FormulaJson))
|
||||
if (string.IsNullOrWhiteSpace(rule.ConditionJson))
|
||||
{
|
||||
throw new ArgumentException("规则 FormulaJson 不能为空", nameof(rule.FormulaJson));
|
||||
throw new ArgumentException("规则 ConditionJson 不能为空", nameof(rule.ConditionJson));
|
||||
}
|
||||
|
||||
// 1. 解析 FormulaJson
|
||||
var conditions = ParseFormulaJson(rule.FormulaJson);
|
||||
// 1. 解析 ConditionJson
|
||||
var conditions = ParseConditionJson(rule.ConditionJson);
|
||||
|
||||
// 2. 生成 Roslyn C# 脚本代码
|
||||
string scriptCode = BuildScriptCode(conditions);
|
||||
@@ -81,32 +81,32 @@ namespace YLErp.Modules.RiskEngine
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析 FormulaJson,提取条件列表
|
||||
/// 解析 ConditionJson,提取条件列表
|
||||
/// </summary>
|
||||
private static List<(string variableCode, string op, object value, string variableType)> ParseFormulaJson(string formulaJson)
|
||||
private static List<(long variableId, string op, object value, string variableType)> ParseConditionJson(string conditionJson)
|
||||
{
|
||||
var result = new List<(string, string, object, string)>();
|
||||
var jObj = JObject.Parse(formulaJson);
|
||||
var result = new List<(long, string, object, string)>();
|
||||
var jObj = JObject.Parse(conditionJson);
|
||||
var conditions = jObj["conditions"] as JArray;
|
||||
|
||||
if (conditions == null || !conditions.Any())
|
||||
{
|
||||
throw new ArgumentException("FormulaJson 中缺少 conditions");
|
||||
throw new ArgumentException("ConditionJson 中缺少 conditions");
|
||||
}
|
||||
|
||||
foreach (var cond in conditions)
|
||||
{
|
||||
string variableCode = cond["variableCode"]?.Value<string>();
|
||||
long variableId = cond["variableId"]?.Value<long>() ?? 0;
|
||||
string op = cond["operator"]?.Value<string>();
|
||||
object value = cond["value"]?.Value<object>();
|
||||
string variableType = cond["variableType"]?.Value<string>() ?? "numeric";
|
||||
|
||||
if (string.IsNullOrWhiteSpace(variableCode) || string.IsNullOrWhiteSpace(op))
|
||||
if (variableId <= 0 || string.IsNullOrWhiteSpace(op))
|
||||
{
|
||||
throw new ArgumentException("条件中缺少 variableCode 或 operator");
|
||||
throw new ArgumentException("条件中缺少 variableId 或 operator");
|
||||
}
|
||||
|
||||
result.Add((variableCode, op, value, variableType));
|
||||
result.Add((variableId, op, value, variableType));
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -115,18 +115,24 @@ namespace YLErp.Modules.RiskEngine
|
||||
/// <summary>
|
||||
/// 根据条件列表生成 Roslyn C# 脚本代码
|
||||
/// 多条件自动用 &&(AND)连接
|
||||
/// TODO: 当前逻辑依赖 variableCode 的 "前缀.属性名" 格式,
|
||||
/// 后续应改为通过 variableId 查变量池获取 VariableExpr,或直接使用 rule.RuleExpr
|
||||
/// </summary>
|
||||
private static string BuildScriptCode(List<(string variableCode, string op, object value, string variableType)> conditions)
|
||||
private static string BuildScriptCode(List<(long variableId, string op, object value, string variableType)> conditions)
|
||||
{
|
||||
var exprParts = new List<string>();
|
||||
|
||||
foreach (var (variableCode, op, value, variableType) in conditions)
|
||||
foreach (var (variableId, op, value, variableType) in conditions)
|
||||
{
|
||||
// 解析 variableCode:前缀.属性名
|
||||
var parts = variableCode.Split('.');
|
||||
// TODO: 通过 variableId 查变量池获取 VariableExpr(如 "trade.StockEqvNotional")
|
||||
// 当前暂用 variableId.ToString() 占位,后续接入变量池查询
|
||||
string variableExpr = variableId.ToString();
|
||||
|
||||
// 解析 variableExpr:前缀.属性名
|
||||
var parts = variableExpr.Split('.');
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
throw new ArgumentException($"variableCode 格式不正确:{variableCode}");
|
||||
throw new ArgumentException($"variableExpr 格式不正确:{variableExpr}(variableId={variableId})");
|
||||
}
|
||||
|
||||
string prefix = parts[0].Trim().ToLower();
|
||||
|
||||
@@ -1,2 +1,125 @@
|
||||
var main = main || {};
|
||||
main.formatOptions = { "trading": { "umprice": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "umpriceP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "umpricePR": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "tradeSinglePrice": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "premiumRateP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "premiumRate": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "tradePrice": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "StockEqvNotional": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "notional": { "trimTailZeros": true, "precision": 9, "grouping": true, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "notionalP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "volatility": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "volatilityP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "greek": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 }, "marginRateP": { "trimTailZeros": true, "percent": true, "precision": 9, "grouping": false, "rounded": true, "minDecimals": 2, "maxDecimals": 9 }, "marginRate": { "trimTailZeros": true, "precision": 9, "grouping": false, "rounded": true, "percent": false, "minDecimals": 2, "maxDecimals": 9 } } };
|
||||
main.formatOptions={
|
||||
"trading": {
|
||||
"umprice": {
|
||||
"precision": 9,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 9,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"umpriceP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"umpricePR": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"tradeSinglePrice": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"premiumRateP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"premiumRate": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"tradePrice": {
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"StockEqvNotional": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"notional": {
|
||||
"precision": 2,
|
||||
"grouping": true,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"notionalP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"volatility": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
},
|
||||
"volatilityP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"greek": {
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"marginRateP": {
|
||||
"percent": true,
|
||||
"precision": 2,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"minDecimals": 2,
|
||||
"maxDecimals": 0
|
||||
},
|
||||
"marginRate": {
|
||||
"precision": 4,
|
||||
"grouping": false,
|
||||
"rounded": true,
|
||||
"percent": false,
|
||||
"minDecimals": 4,
|
||||
"maxDecimals": 2
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -180,6 +180,14 @@ 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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user