From 76af939332c04e8a56a1ec3a346c2f81298aae84 Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 8 Jul 2026 08:51:33 +0800 Subject: [PATCH] =?UTF-8?q?feat(valuation):=20=E6=A1=86=E6=9E=B6=E5=90=88?= =?UTF-8?q?=E7=BA=A6Tab=20=E6=8E=A5=E5=85=A5=E5=8F=AF=E6=8A=98=E5=8F=A0?= =?UTF-8?q?=E5=88=86=E7=BB=84=E8=A1=A8=E5=A4=B4=20+=20=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E5=AF=B9=E9=BD=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 对应需求《估值模块V1》模块一:日终持仓风险_互换 - 框架合约Tab 改动: 1. colModelGridEodSwap 列按需求2.2分组重排(组内列连续,满足setGroupHeaders要求) - 互换类型移至基本信息组(原在末尾) 2. 字段命名对齐需求用词(纯label改动,不改name/index): - 合约利率端待实现收益 → 合约利息端待实现收益 - 预付金字段 → 保证金(收取/支付 初始/维持保证金) 3. 新增 eodSwapGroupConfig 分组配置(7组:基本信息/名义本金/标的市值/浮动端/利息端/保证金/估值与实现收益) 4. gridComplete 在 setcolumnChooser 完成后初始化可折叠分组表头 缺失字段(TODO,待后端确认): - 标的类型、期间付息/分红、付息方式、合约估值(两口径) 测试要点:框架合约Tab表头分组合并、点击折叠/展开、footer汇总行(DV)正常、列设置功能正常 --- .../Scripts/app/swaptrade/EodPositionRisks.js | 122 ++++++++++++------ 1 file changed, 81 insertions(+), 41 deletions(-) diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js index 5abf3e14..3e05e3a9 100644 --- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js +++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/EodPositionRisks.js @@ -456,7 +456,12 @@ function colModelGridEodPosition() { return colModelGrid; } //框架合约table +//TODO(估值模块V1-缺失字段): 以下需求字段本轮未实现,待后端确认数据来源后补充: +// - 期间付息/分红(浮动端分组) +// - 付息方式、合约估值(到期轧差口径/期间支付派息口径)(估值与实现收益分组) +// - 标的类型(基本信息分组) function colModelGridEodSwap() { + //按需求《估值模块V1》2.2 分组定义排列列顺序,确保组内列连续(setGroupHeaders 要求) var colModelGrid = [{ name: 'position.id', label: 'id', @@ -475,7 +480,9 @@ function colModelGridEodSwap() { align: 'center', hidden: true, optionHide: true - }, { + }, + //=== 基本信息 === + { name: 'position.ValueDate', label: '交易日', index: 'position.ValueDate', @@ -513,6 +520,15 @@ function colModelGridEodSwap() { width: 90, align: 'center', }, { + name: 'SwapTradeTypeStr', + label: '互换类型', + index: 'SwapTradeTypeStr', + width: 100, + align: 'center', + sortable: false + }, + //=== 名义本金 === + { name: 'position.NotionalValue', label: '合约名义本金', index: 'position.NotionalValue', @@ -533,7 +549,9 @@ function colModelGridEodSwap() { width: 150, align: 'center', formatter: StockEqvNotionalFormat - }, { + }, + //=== 标的市值 === + { name: 'position.MarketValueLong', label: '合约多头标的市值', index: 'position.MarketValueLong', @@ -547,21 +565,57 @@ function colModelGridEodSwap() { width: 150, align: 'center', formatter: StockEqvNotionalFormat - }, { + }, + //=== 浮动端 === + { name: 'position.FloatingPnL', label: '合约浮动端待实现收益', index: 'position.FloatingPnL', width: 150, align: 'center', formatter: StockEqvNotionalFormat, - }, { + }, + //=== 利息端 === + { name: 'position.InterestPnL', - label: '合约利率端待实现收益', + label: '合约利息端待实现收益', index: 'position.InterestPnL', width: 150, align: 'center', formatter: otcformat.trading.notional, + }, + //=== 保证金 === + { + name: 'position.InitMarginGain', + label: '收取对手方初始保证金', + index: 'position.InitMarginGain', + width: 150, + align: 'center', + formatter: StockEqvNotionalFormat, }, { + name: 'position.PostionMarginGain', + label: '收取对手方维持保证金', + index: 'position.PostionMarginGain', + width: 150, + align: 'center', + formatter: StockEqvNotionalFormat, + }, { + name: 'position.InitMarginLoss', + label: '支付初始保证金', + index: 'position.InitMarginLoss', + width: 150, + align: 'center', + formatter: StockEqvNotionalFormat, + }, { + name: 'position.PostionMarginLoss', + label: '支付维持保证金', + index: 'position.PostionMarginLoss', + width: 150, + align: 'center', + formatter: StockEqvNotionalFormat, + }, + //=== 估值与实现收益 === + { name: 'position.PostionValue', label: '合约持仓价值', index: 'position.PostionValue', @@ -582,34 +636,6 @@ function colModelGridEodSwap() { width: 150, align: 'center', formatter: StockEqvNotionalFormat, - }, { - name: 'position.InitMarginGain', - label: '收取对手方初始预付金', - index: 'position.InitMarginGain', - width: 150, - align: 'center', - formatter: StockEqvNotionalFormat, - }, { - name: 'position.PostionMarginGain', - label: '收取对手方维持预付金', - index: 'position.PostionMarginGain', - width: 150, - align: 'center', - formatter: StockEqvNotionalFormat, - }, { - name: 'position.InitMarginLoss', - label: '支付初始预付金', - index: 'position.InitMarginLoss', - width: 150, - align: 'center', - formatter: StockEqvNotionalFormat, - }, { - name: 'position.PostionMarginLoss', - label: '支付维持预付金', - index: 'position.PostionMarginLoss', - width: 150, - align: 'center', - formatter: StockEqvNotionalFormat, }, { name: 'position.dv01', label: 'DV', @@ -622,26 +648,40 @@ function colModelGridEodSwap() { if (abs < 0.0001) return "0"; return cellvalue.toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 4 }); }, - }, { - name: 'SwapTradeTypeStr', - label: '互换类型', - index: 'SwapTradeTypeStr', - width: 100, - align: 'center', - sortable: false } ]; return colModelGrid; } +//框架合约分组配置(对应需求《估值模块V1》2.2 字段定义) +//columns 使用 colModel.name;组内列在 colModel 中必须连续 +var eodSwapGroupConfig = [ + { title: '基本信息', columns: ['position.ValueDate', 'AssetBookName', 'ClientName', 'SwapTradeNo', 'StructureType', 'SwapTradeTypeStr'] }, + { title: '名义本金', columns: ['position.NotionalValue', 'position.NotionalValueLong', 'position.NotionalValueShort'] }, + { title: '标的市值', columns: ['position.MarketValueLong', 'position.MarketValueShort'] }, + { title: '浮动端', columns: ['position.FloatingPnL'] }, + { title: '利息端', columns: ['position.InterestPnL'] }, + { title: '保证金', columns: ['position.InitMarginGain', 'position.PostionMarginGain', 'position.InitMarginLoss', 'position.PostionMarginLoss'] }, + { title: '估值与实现收益', columns: ['position.PostionValue', 'position.TdRealizedPnL', 'position.RealizedPnL', 'position.dv01'] } +]; + function gridComplete() { var jgrid = $(this); if (arguments[0].Sum) { jgrid.footerData("set", { 'position.dv01': arguments[0].Sum["DV"] }); } - main.setcolumnChooser(jgrid, page.configcolumn_data); + //框架合约Tab:在列设置应用完成后初始化可折叠分组表头 + //setcolumnChooser 会 remapColumns 重排列,必须在它完成后再 setGroupHeaders,否则分组边界错位 + if (page.tabIndex == 2) { + var defer = main.setcolumnChooser(jgrid, page.configcolumn_data); + $.when(defer).done(function () { + main.initCollapsibleGroupHeaders(jgrid, eodSwapGroupConfig); + }); + } else { + main.setcolumnChooser(jgrid, page.configcolumn_data); + } $(window).resize(); }