refactor(swap): ComposePage接缝-7虚方法+DB调用替换(testable迁移)

ComposePage(流水合成持仓)是swap_flow_event→swap_position的核心转换,
每笔开仓/平仓/互换都经过这里(176行)。

新增7个protected virtual虚方法(Seams):
- FindTrade/FindTradeExtend/FindSwapPositions
- FindEodSwapPositions/FindEodSwap
- AddSwapEvent/ExecuteInTransaction

ComposePage内部DB调用替换为调虚方法:
- DbContext.trade.Find → FindTrade
- DbContext.trade_extend.FirstOrDefault → FindTradeExtend
- DbContext.eod_swap_position.Where → FindEodSwapPositions
- DbContext.swap_position.Where → FindSwapPositions
- DbContext.eod_swap.FirstOrDefault → FindEodSwap
- new SwapEventService.AddSwapEventDate → AddSwapEvent
- DbContext.SaveChanges → SaveAllChanges(已有)
- ComposePage可见性private→protected

生产代码行为不变(虚方法默认实现=原逻辑)。
验证: 100个测试全通过(T0/T1=89+DealInterests=7+ConsumedInterest=4)。
This commit is contained in:
hjhan
2026-07-02 08:28:13 +08:00
parent f501ee95a7
commit 014edaed45
@@ -79,6 +79,62 @@ namespace YLErp.Modules.SwapModule
grossPrice, orginPv, add, settment, newCalcLast, closeList);
}
/// <summary>查找交易(生产: DbContext.trade.Find;测试: 内存字典)</summary>
protected virtual trade FindTrade(int swapTradeId)
{
return DbContext.trade.Find(swapTradeId);
}
/// <summary>查找交易扩展(生产: DbContext.trade_extend;测试: 内存字典)</summary>
protected virtual trade_extend FindTradeExtend(int tradeId)
{
return DbContext.trade_extend.FirstOrDefault(x => x.TradeId == tradeId);
}
/// <summary>查找指定日期范围的 eod 持仓(生产: DbContext.eod_swap_position.Where;测试: 内存列表)</summary>
protected virtual List<eod_swap_position> FindEodSwapPositions(int swapTradeId, DateTime preSettleDate)
{
return DbContext.eod_swap_position.Where(x => x.SwapTradeId == swapTradeId && !x.Invalid && x.ValueDate >= preSettleDate).ToList();
}
/// <summary>查找交易持仓(生产: DbContext.swap_position.Where;测试: 内存列表)</summary>
protected virtual List<swap_position> FindSwapPositions(int swapTradeId)
{
return DbContext.swap_position.Where(x => x.SwapTradeId == swapTradeId && !x.Invalid).ToList();
}
/// <summary>查找框架合约日终汇总(生产: DbContext.eod_swap.FirstOrDefault;测试: 内存字典)</summary>
protected virtual eod_swap FindEodSwap(int swapTradeId, DateTime valueDate)
{
return DbContext.eod_swap.FirstOrDefault(x => x.SwapTradeId == swapTradeId && x.ValueDate == valueDate);
}
/// <summary>添加互换事件(生产: new SwapEventService(this).AddSwapEventDate;测试: 收集到列表)</summary>
protected virtual swap_event AddSwapEvent(DateTime tradeDate, int swapTradeId, int eventType, string data, int clientCashId, bool save, string reason)
{
return new SwapEventService(this).AddSwapEventDate(tradeDate, swapTradeId, eventType, data, clientCashId, save, reason);
}
/// <summary>在事务中执行(生产: BeginTransaction/Commit/Rollback;测试: 直接执行不包事务)</summary>
protected virtual void ExecuteInTransaction(Action action)
{
var trans = DbContext.Database.BeginTransaction();
try
{
action();
trans.Commit();
}
catch
{
trans.Rollback();
throw;
}
finally
{
trans.Dispose();
}
}
#endregion
/// <summary>
@@ -633,7 +689,7 @@ namespace YLErp.Modules.SwapModule
/// </summary>
/// <param name="swapTradeId">互换交易id</param>
/// <param name="tradeDate">清算日期</param>
private void ComposePage(int swapTradeId, List<swap_flow_event> flowEvents, DateTime tradeDate, bool needTrans = true)
protected void ComposePage(int swapTradeId, List<swap_flow_event> flowEvents, DateTime tradeDate, bool needTrans = true)
{
// 同一标的 事件编码一致
var eventQuery = flowEvents.OrderBy(o => o.PositionId).ToList();
@@ -647,21 +703,16 @@ namespace YLErp.Modules.SwapModule
{
UnwindData unwindData = new UnwindData();
unwindData.SwapTradeId = swapTradeId;
var swapEvent = new SwapEventService(this).AddSwapEventDate(tradeDate, swapTradeId, (int)SwapEventTypeEnum., string.Empty, 0, true, "系统操作-自动合成持仓");//不用回退,回退时过滤该事件类型
var td = DbContext.trade.Find(swapTradeId);
var swapEvent = AddSwapEvent(tradeDate, swapTradeId, (int)SwapEventTypeEnum., string.Empty, 0, true, "系统操作-自动合成持仓");
var td = FindTrade(swapTradeId);
var preSettleDate = GetPreValueDate(tradeDate);//上一交易日期
List<int> eventTyps = new List<int>() { (int)SwapEventTypeEnum., (int)SwapEventTypeEnum., (int)SwapEventTypeEnum. };
List<int> removeEventTyps = new List<int>() { (int)SwapEventTypeEnum., (int)SwapEventTypeEnum., (int)SwapEventTypeEnum. };
ClearSwapPositions(td, tradeDate, removeEventTyps, false);
td.trade_extend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == swapTradeId);
var allEodPositions = DbContext.eod_swap_position.Where(x => x.SwapTradeId == swapTradeId && !x.Invalid && x.ValueDate >= preSettleDate);
//var curentInvalidEodPostions = allEodPositions.Where(x => x.SwapTradeId == swapTradeId && !x.Invalid && x.ValueDate >= tradeDate);//废弃当前清算日期之后的归档数据
//curentInvalidEodPostions.ForEach(x =>
//{
// x.Invalid = true;
//});
td.trade_extend = FindTradeExtend(swapTradeId);
var allEodPositions = FindEodSwapPositions(swapTradeId, preSettleDate);
var eodPositions = allEodPositions.Where(x => x.ValueDate == preSettleDate).ToList();//上一日终持仓信息
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == swapTradeId && !x.Invalid).ToList();
var positions = FindSwapPositions(swapTradeId);
var oriPositions = positions.Where(x => x.IsInitial).ToList();
var realPositions = positions.Where(x => !x.IsInitial).ToList();
var fpositions = positions.Where(x => x.PosiDirection > 0).ToList();
@@ -669,7 +720,7 @@ namespace YLErp.Modules.SwapModule
decimal totalPosiNotionalValue = 0;//总剩余名义本金
decimal tdCloseNotionalValue = 0;//当日平仓名义本金
var preDealDate = GetPreDealDate(swapTradeId, tradeDate, eventTyps);//上一次平仓/互换/自动互换事件日期
var lastEodSwap = DbContext.eod_swap.FirstOrDefault(x => x.SwapTradeId == swapTradeId && x.ValueDate == preSettleDate);
var lastEodSwap = FindEodSwap(swapTradeId, preSettleDate);
decimal stockEqvNotional = lastEodSwap == null ? Convert.ToDecimal(td.OriginalStockEqvNotional ?? 0) : lastEodSwap.NotionalValue;//上一日名义本金
unwindData.NotionalValue = stockEqvNotional;
List<swap_flow_event> longshortCloseInterests = new List<swap_flow_event>();
@@ -795,9 +846,9 @@ namespace YLErp.Modules.SwapModule
unwindData.PosiNotionalValue = allPosiNotionalValue;
unwindData.CloseNotionalValue = tdCloseNotionalValue;
swapEvent.EventData = JsonHelper.Serialize(unwindData);
DbContext.SaveChanges();
SaveAllChanges();
SaveEodSwap(td, tradeDate, preSettleDate);
DbContext.SaveChanges();
SaveAllChanges();
trans?.Commit();
}
catch (Exception ex)