feat(swaptrade): 实现收益结算审批页面期末价格回显功能

- 在incomeSwapTrade.js中修改TradingAmountAvg赋值逻辑,区分普通打开和审批打开场景
- 新增resolveIncomeTradingAmountAvg函数处理审批回显和普通默认值的不同逻辑
- 审批打开时保留已提交的期末全价,普通打开时使用期初全价作为默认值
- 统一债券价格×100缩放到界面百分比显示格式
- 添加单元测试验证审批回显和普通打开的功能差异
This commit is contained in:
张名锐
2026-07-17 13:17:28 +08:00
parent 4f23ad9c0f
commit 7fac6e13a8
3 changed files with 27 additions and 3 deletions
+11
View File
@@ -24,6 +24,17 @@ describe('回归守卫:曾出 bug 的纯函数', () => {
expect(SwapCalc.deriveTradingAmountAvg(1.02, 100)).toBe(102);
});
test('收益结算审批回显提交的期末价格', () => {
expectClose(
SwapCalc.resolveIncomeTradingAmountAvg(0.98, 0.80, 100, true),
80,
'债券审批应把已提交相对价0.80还原为界面值80');
expectClose(
SwapCalc.resolveIncomeTradingAmountAvg(0.98, 0.80, 100, false),
98,
'普通打开仍以期初全价98作为默认期末价');
});
// 3c5f25a5FloatPnlSum 必须保留 2 位小数
test('calcFloatPnlSum 保留 2 位 (守卫 3c5f25a5)', () => {
expectClose(SwapCalc.calcFloatPnlSum(100.456, 1, 0.5, 0), 101.96, '100.456+1+0.5=101.956→101.96');
@@ -86,9 +86,13 @@ const vue = new Vue({
this.initPosiGrossPrice = this.floatPosition.PosiGrossPrice;
// 互换标的价格固定为期初净价,与平仓不同不需要用户填写
// 期初净价入库为相对价(如1.02),需转换为界面百分比形态(102),与平仓页保持一致
// 守卫: 期末全价必须用 PosiGrossPrice(全价) 且债券 ×100 转界面态
// 对应历史 bug dcf649f2(错用净价) / 20ea93d8(×100 缩放丢失); 外置到 swapCalc.deriveTradingAmountAvg
this.floatPosition.TradingAmountAvg = SwapCalc.deriveTradingAmountAvg(this.initPosiGrossPrice, this.multiplier);
// 普通打开时用期初全价作为默认值;审批打开时必须保留已提交的期末全价,不能再被期初全价覆盖。
// 两种来源入库时都是相对价,债券统一 ×100 还原为界面百分比态。
this.floatPosition.TradingAmountAvg = SwapCalc.resolveIncomeTradingAmountAvg(
this.initPosiGrossPrice,
this.floatPosition.TradingAmountAvg,
this.multiplier,
isUseApproval);
this.interestList = model.FlowEvents.filter((item) => {
return item.InterestMode == 1 || item.InterestMode == 2 || item.InterestMode == 7 || item.InterestMode == 8 || item.InterestMode == 9;
});
@@ -48,6 +48,14 @@
return posiGrossPrice * multiplier;
}
// 普通打开时以期初全价作为期末价默认值;审批打开时回显已提交的期末相对价。
function resolveIncomeTradingAmountAvg(posiGrossPrice, submittedTradingAmountAvg, multiplier, isUseApproval) {
var relativePrice = isUseApproval && submittedTradingAmountAvg !== undefined && submittedTradingAmountAvg !== null
? submittedTradingAmountAvg
: posiGrossPrice;
return relativePrice * multiplier;
}
// 金额四舍五入到指定小数位(避免 0.1+0.2 类浮点误差)
function roundMoney(value, digits) {
return roundHalfAwayFromZero(value, digits);
@@ -196,6 +204,7 @@
roundHalfAwayFromZero: roundHalfAwayFromZero,
getPriceScale: getPriceScale,
deriveTradingAmountAvg: deriveTradingAmountAvg,
resolveIncomeTradingAmountAvg: resolveIncomeTradingAmountAvg,
roundMoney: roundMoney,
calcFloatPnlSum: calcFloatPnlSum,
calcStockEqvNotional: calcStockEqvNotional,