Files
zszq-trs/项目文档/估值模块重构-前端改造说明.md
hjhan 5e27d6cef8 docs(valuation): 新增估值模块前端改造说明文档
记录:
- 改造范围、路径A决策依据、方案对比(否决otcdms-ui/free-jqGrid的理由)
- 分组配置映射表(需求字段 ↔ colModel.name ↔ 后端字段)
- 缺失字段清单(TODO,待后端确认):标的类型/期间付息分红/付息方式/合约估值两口径/保证金利息/期间分红/预付金系列/TRS估值
- 已知约束:冻结列冲突绕法、setcolumnChooser兼容、导出口径区分
- 测试要点、后续工作
2026-07-08 08:57:46 +08:00

182 lines
9.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 估值模块重构 - 前端改造说明
> 对应需求:《估值模块V1》(`估值模块V1.pdf`)
> 分支:`glms/feature/1.4.2`
> 改造时间:2026-07
## 一、改造范围与决策
### 背景
需求要求重构两个页面的互换相关 Tab:
1. **日终持仓风险_互换** 的「框架合约」Tab —— 适配内部盯市场景
2. **每日估值报告** 的「互换估值」Tab —— 适配对客发送场景
### 决策:路径 A(改现有 jqGrid 前端)
经对比分析(详见下方"方案对比"),选择**直接改现有 jqGrid 前端**,理由:
- 计算逻辑全在后端 `SwapEodPositionService.cs`,前端只做格式化展示 —— 改动可控
- 数据接口零改动,新旧同源,便于对比验证
- 不换库(不升级到 free-jqGrid),零全站回归风险
- 工作量最小
### 方案对比(已否决)
| 方案 | 否决理由 |
|------|----------|
| otcdms-ui 新建 Vue 页面 | 需加 Java 中转层,工作量大;数据仍来自 C#,未实现解耦 |
| 升级 free-jqGrid | 原生支持折叠,但需回归全站 40+ 处 grouping,风险过大 |
## 二、改造内容
### 提交 1:通用工具(`utils.js`
新增两个通用函数,所有 jqGrid 页面可复用:
- `main.initCollapsibleGroupHeaders(jgrid, groupConfig)`:生成合并表头 + 点击折叠/展开
- `main.refreshCollapsibleGroupHeaders(jgrid)`:列重排后重建分组边界
- `main.exportVisibleColumnsToExcel(jgrid, fileName)`:零依赖导出可见列为 Excel
### 提交 2:框架合约 Tab`EodPositionRisks.js`
- colModel 按需求 2.2 分组重排(组内列连续)
- 字段命名对齐(预付金→保证金、利率端→利息端)
- 接入可折叠分组表头(7 组)
- **缺失字段已标注 TODO**(见第四节)
### 提交 3:框架合约 Tab 导出
- 恢复导出按钮(原被注释)
- 接入 `exportVisibleColumnsToExcel`,与折叠状态联动
### 提交 4:互换估值 Tab`TradeMarketReport_EodPosition.js`
- 新增分组配置(4 组),现有列顺序天然满足连续性,无需重排
- 接入可折叠分组表头,保留异常行标红逻辑
- 新增簿记账户筛选(需求 3.1
- 新增「导出互换估值」按钮,与现有 DownLoadReport 独立
## 三、分组配置映射表
### 模块一:框架合约 Tab`eodSwapGroupConfig`
| 分组 | 需求字段 | colModel.name | 后端字段 |
|------|----------|---------------|----------|
| 基本信息 | 交易日 | `position.ValueDate` | `eod_swap.ValueDate` |
| | 簿记账户 | `AssetBookName` | 关联 asset_unit |
| | 交易对手方 | `ClientName` | 关联 client |
| | 互换交易编码 | `SwapTradeNo` | `eod_swap.SwapTradeNo` |
| | 产品类型 | `StructureType` | trade.StructureType |
| | 互换类型 | `SwapTradeTypeStr` | 枚举翻译 |
| 名义本金 | 合约名义本金 | `position.NotionalValue` | `eod_swap.NotionalValue` |
| | 合约多头名义本金 | `position.NotionalValueLong` | 同上 |
| | 合约空头名义本金 | `position.NotionalValueShort` | 同上 |
| 标的市值 | 合约多头标的市值 | `position.MarketValueLong` | 计算字段 |
| | 合约空头标的市值 | `position.MarketValueShort` | 计算字段 |
| 浮动端 | 合约浮动端待实现收益 | `position.FloatingPnL` | `eod_swap.FloatingPnL` |
| 利息端 | 合约利息端待实现收益 | `position.InterestPnL` | `eod_swap.InterestPnL` |
| 保证金 | 收取对手方初始保证金 | `position.InitMarginGain` | 计算字段 |
| | 收取对手方维持保证金 | `position.PostionMarginGain` | 计算字段 |
| | 支付初始保证金 | `position.InitMarginLoss` | 计算字段 |
| | 支付维持保证金 | `position.PostionMarginLoss` | 计算字段 |
| 估值与实现收益 | 合约持仓价值 | `position.PostionValue` | `eod_swap.PostionValue` |
| | 合约当日实现收益 | `position.TdRealizedPnL` | `eod_swap.TdRealizedPnL` |
| | 合约已实现收益 | `position.RealizedPnL` | `eod_swap.RealizedPnL` |
| | DV | `position.dv01` | `eod_swap.dv01` |
### 模块二:互换估值 Tab`eodSwapValuationGroupConfig`
| 分组 | 需求字段 | colModel.name | 后端字段 |
|------|----------|---------------|----------|
| 基本信息 | 交易编号 | `TradeNumber` | trade.TradeNumber |
| | 确认书编号 | `ConfrimNo` | trade.ConfrimNo |
| | 交易对手 | `ClientName` | 关联 client |
| | 起始日 | `position.PosiStartDate` | swap_position.PosiStartDate |
| | 估值日 | `position.ValueDate` | swap_position.ValueDate |
| | 参考标的 | `position.UnderlyingCode` | swap_position.UnderlyingCode |
| 利率与规模 | 利差 | `InterestRate` | 计算字段 |
| | 基准利率 | `position.FloatRateUnderlyingCode` | swap_position |
| | 当日适用基准利率 | `position.FloatRate` | 计算字段 |
| | 标的名义金额 | `position.PosiNotionalValue` | swap_position |
| | 标的数量 | `position.PosiQuantity` | swap_position |
| | 期间付息 | `PeriodAmount` | 查询时现算 |
| 价格 | 期初标的交割全价 | `position.PosiGrossPrice` | swap_position |
| | 期初标的成交收益率 | `InitYtm` | trade_swap |
| | 期末标的交割全价 | `position.UnderlyingPrice` | swap_position |
| | 实际期限 | `DayCount` | 查询时现算 |
| 收益 | 浮动利率(绝对) | `FloatRateAbs` | 查询时现算 |
| | 利率收益金额 | `InterestAmount` | 查询时现算 |
| | 开仓交易费用 | `position.PosiFeePending` | swap_position |
| | 浮动收益金额 | `position.PosiProfitSum` | swap_position |
| | 净额结算金额 | `NetSettmentAmount` | 查询时现算 |
## 四、缺失字段清单(TODO,待后端确认)
以下需求字段本轮**未实现**,需后端确认数据来源后单独提交补充。
### 模块一(框架合约 Tab
| 需求字段 | 需求分组 | 后端状态 | 待办 |
|----------|----------|----------|------|
| 标的类型 | 基本信息 | 待确认 | 加 colModel,值"现券/ETF/指数" |
| 名义本金(概念性) | 基本信息 | 待确认 | 可能与合约名义本金重复 |
| 期间付息/分红 | 浮动端 | 待确认 | `eod_swap` 是否有此字段 |
| 付息方式 | 估值与实现收益 | 待确认 | 到期轧差/派息日支付,来源 trade 要素 |
| 合约估值(到期轧差口径) | 估值与实现收益 | 待确认 | `FloatingPnL + InterestPnL + 期间付息` |
| 合约估值(期间支付派息口径) | 估值与实现收益 | 待确认 | `FloatingPnL + InterestPnL` |
| 保证金利息(收取/支付) | 保证金 | 待确认 | 现状 colModel 无此字段 |
### 模块二(互换估值 Tab
| 需求字段 | 需求分组 | 后端状态 | 待办 |
|----------|----------|----------|------|
| 期间分红 | 利率与规模 | 待确认 | ETF 适用 |
| 预付金利率 | 预付金(新分组) | 待确认 | |
| 预付金利息 | 预付金 | 待确认 | |
| 期初预付金 | 预付金 | 待确认 | 我方收取为正,支付为负 |
| 追加预付金 | 预付金 | 待确认 | 我方收取为正,支付为负 |
| TRS估值 | 汇总(新分组) | 待确认 | `净额结算金额 + 期初预付金 + 追加预付金` |
## 五、已知约束
### 1. 冻结列与 groupHeader 冲突
jqGrid 4.5.4 的 `setFrozenColumns``setGroupHeaders` 合用有限制。
参考 `clientRiskMonitor.js:284-285` 的绕法:先 `destroyFrozenColumns``setFrozenColumns`
本改造的目标页面未使用冻结列,暂无影响。
### 2. setcolumnChooser 兼容
`main.setcolumnChooser``remapColumns` 重排列,且不重建 groupHeader。
解决方案:在 `gridComplete` 中用 `$.when(defer).done(...)` 确保 `setcolumnChooser` 完成后再初始化分组表头。
若用户自定义列顺序打散了分组,`buildGroupHeaders` 会按实际可见列动态计算最接近的分组边界。
### 3. 导出口径区分
| 导出方式 | 触发 | 数据源 | 口径 |
|----------|------|--------|------|
| 前端可见列导出(新增) | 「导出」按钮 | jqGrid 当前页数据 | 与页面显示一致 |
| 后端模板导出(现有) | `DownLoadReport` | C# Service | 报告格式,口径不同 |
两者独立,需在 UI 和文档上区分,避免用户混淆。
### 4. 导出格式
当前前端导出为 `.xls`HTML table + ms-excel MIME),非严格 `.xlsx`
若需严格 xlsx,后续可引入 SheetJS(项目已有 `Statics/libs/export/excellentexport.js`,但无实际使用范例)。
## 六、测试要点
### 框架合约 Tab
1. 打开「风险控制-日终持仓风险_互换-框架合约」
2. 表头按 7 组分组合并显示
3. 点击各分组表头能收起(▶)/展开(▼)
4. 展开后列对齐不错位
5. footer 汇总行(DV)不受折叠影响
6. 「列设置」(configure.png)功能正常
7. 点击「导出」生成 Excel,列与页面可见列一致
### 互换估值 Tab
1. 打开「结算管理-每日估值报告-互换估值」
2. 表头按 4 组分组合并显示
3. 折叠交互正常
4. 异常行标红(dataError)不受影响
5. 簿记账户筛选生效(需后端支持 BookId 参数)
6. 「导出互换估值」按钮可用
7. 现有「发送报告/下载报告」功能不受影响
## 七、后续工作
1. **缺失字段补齐**(见第四节 TODO)—— 需后端确认字段来源
2. **命名对齐回归** —— 预付金→保证金 改动需确认不影响现有用户习惯
3. **导出格式升级** —— 若需严格 xlsx,引入 SheetJS
4. **预付金/TRS估值 分组** —— 缺失字段补齐后,互换估值 Tab 新增「预付金」「汇总」两个分组