From dc3a6e9f779425a1ebd5bda7ab73f093f15bbafd Mon Sep 17 00:00:00 2001 From: hjhan Date: Wed, 1 Jul 2026 17:21:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor(swap):=20=E9=98=B6=E6=AE=B51b=20SwapEo?= =?UTF-8?q?dPositionService=E5=8A=A0=E8=99=9A=E6=96=B9=E6=B3=95=E6=8E=A5?= =?UTF-8?q?=E7=BC=9D(testable=E8=BF=81=E7=A7=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 加3个protected virtual虚方法(Seams接缝),不改变生产行为: - PersistEodSwapPosition: 持久化eod持仓(原DbContext.Add+UpdateDbOption) - SaveAllChanges: 保存变更(原DbContext.SaveChanges) - GetCurrencyRate: 获取汇率(原new EodCurrencyRateService) 将4个利息归档分支方法里的直接DB调用替换为调虚方法: - SaveEodInterestPosition(互换分支) - SaveAutoEodInterestPosition(自动互换分支) - SaveAutoEodWithCloseInterestPosition(平仓分支) - SaveEodInterestPositionCopy(普通计息分支) 测试子类override这些虚方法即可在内存中运行收盘逻辑, 不连数据库。生产代码行为完全不变(虚方法默认实现=原逻辑)。 验证: GetInterestsUnitTest_T0/T1 89个测试全通过,无回归。 --- .../SwapModule/SwapEodPositionService.cs | 66 ++++++++++++------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index f68558e0..230f99d3 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -30,6 +30,36 @@ namespace YLErp.Modules.SwapModule { } + + #region 可测试化接缝(Seams)——override 这些虚方法可在测试中替换 DB/外部调用,生产代码行为不变 + + /// 持久化 eod 持仓记录(生产: DbContext.Add;测试: 收集到列表) + protected virtual void PersistEodSwapPosition(eod_swap_position position) + { + if (position.id == 0) + { + DbContext.eod_swap_position.Add(position); + } + else + { + UpdateDbOption(position); + } + } + + /// 保存所有变更(生产: DbContext.SaveChanges;测试: 计数) + protected virtual void SaveAllChanges() + { + DbContext.SaveChanges(); + } + + /// 获取汇率(生产: EodCurrencyRateService;测试: 返回固定值) + protected virtual double GetCurrencyRate(string quoteCurrency, string settlementCurrency, DateTime valueDate, bool seekPreday, CurrencyRateType currencyRateType) + { + return new EodCurrencyRateService(UserInfo).GetCurrencyRate(quoteCurrency, settlementCurrency, valueDate, seekPreday, currencyRateType); + } + + #endregion + /// /// 多空组合 互换流水合成持仓 /// @@ -845,13 +875,10 @@ namespace YLErp.Modules.SwapModule //累计已实现 newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; - var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate - , seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); + var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true, + position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); - if (newEodPayPosition.id == 0) - { - DbContext.eod_swap_position.Add(newEodPayPosition); - } + PersistEodSwapPosition(newEodPayPosition); } /// /// 自动互换用,当日无互换,当日无平仓 @@ -982,13 +1009,10 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; - var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate - , seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); + var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true, + position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); - if (newEodPayPosition.id == 0) - { - DbContext.eod_swap_position.Add(newEodPayPosition); - } + PersistEodSwapPosition(newEodPayPosition); Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}"); return interests; } @@ -1120,14 +1144,11 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; ; - var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate - , seekPreday: true, currencyRateType: position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); + var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true, + position.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); Log.Info($"即将插入数据库的 newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}"); - if (newEodPayPosition.id == 0) - { - DbContext.eod_swap_position.Add(newEodPayPosition); - } + PersistEodSwapPosition(newEodPayPosition); return interests; } @@ -1245,14 +1266,11 @@ namespace YLErp.Modules.SwapModule newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio; newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee; newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee; - var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate - , seekPreday: true, currencyRateType: eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); + var currencyRate = GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate, true, + eodPayPosition.InterestDirection == (int)SwapDirectionEnum.收取 ? CurrencyRateType.Buy : CurrencyRateType.Sell); newEodPayPosition.TdCurrency = Convert.ToDecimal(currencyRate); Log.Info($"the last newEodPayPosition is {JsonHelper.Serialize(newEodPayPosition, false)}"); - if (newEodPayPosition.id == 0) - { - DbContext.eod_swap_position.Add(newEodPayPosition); - } + PersistEodSwapPosition(newEodPayPosition); } ///