From cbb5c88aa879e1a4a9ead7dd12ed366e63b82814 Mon Sep 17 00:00:00 2001 From: hjhan Date: Fri, 3 Jul 2026 18:30:33 +0800 Subject: [PATCH] =?UTF-8?q?refactor(swap):=20SwapPositionCompose=E8=A1=A55?= =?UTF-8?q?=E4=B8=AAseam+=E4=BA=8B=E5=8A=A1=E9=87=8D=E6=9E=84=E4=B8=BAExec?= =?UTF-8?q?uteInTransaction?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SwapEodPositionService 新增5个 protected virtual seam(SwapPositionCompose路径): - FindActiveSwapTrades(DateTime, IEnumerable): 查活跃互换交易 - FindAllSwapPositions(List): 查所有持仓(含初始+实际) - FindTradeExtends(List): 批量查交易扩展 - FindEodSwapsByDate(DateTime): 查指定日期日终汇总 - FindFlowEvents(int, DateTime): 查交易指定日期的完成流水事件 SwapPositionCompose 方法体重构: - 5处内联DbContext查询替换为seam调用 - 事务(BeginTransaction/Commit/Rollback)重构为ExecuteInTransaction lambda - SaveChanges替换为SaveAllChanges seam - 复用已有FindEodSwapPositions seam(替代内联eod_swap_position查询) 为零行为变更(seam生产实现=原代码,ExecuteInTransaction=原事务逻辑)。 SwapModule 173测试全绿,无回归。为SwapPositionComposeScenarioTest铺路。 --- .../SwapModule/SwapEodPositionService.cs | 95 +++++++++++-------- 1 file changed, 54 insertions(+), 41 deletions(-) diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs index 9007286c..4f885bb4 100644 --- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs +++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs @@ -167,6 +167,51 @@ namespace YLErp.Modules.SwapModule return new BondPaymentService(UserInfo).CalcPayment(underlyingCode, fromDate, toDate, qty, shortRatio, directionRatio); } + // ---- SwapPositionCompose 路径专用 seam(借鉴 testable 分支)---- + + /// 查找收盘所需的活跃互换交易(生产: DbContext.trade.Where;测试: 内存列表) + protected virtual List FindActiveSwapTrades(DateTime settleDate, IEnumerable clientIds) + { + var tradePredicate = PredicateBuilder.Create(n => n.ValidState != ConsGlobal.InValid + && n.TradeType == "收益互换" + && n.TradeDate <= settleDate + && n.ExerciseDate >= settleDate + && (n.TradeStatus == ConsTrade.确认成交 || n.UnWindDate >= settleDate) + ); + if (clientIds != null && clientIds.Any()) + { + tradePredicate = tradePredicate.And(x => clientIds.Contains(x.ClientId)); + } + return DbContext.trade.Where(tradePredicate).ToList(); + } + + /// 查找交易的所有持仓(含初始+实际,生产: DbContext.swap_position;测试: 内存列表) + protected virtual List FindAllSwapPositions(List tradeIds) + { + return DbContext.swap_position.Where(t => tradeIds.Contains(t.SwapTradeId) && !t.Invalid).ToList(); + } + + /// 批量查找交易扩展(生产: DbContext.trade_extend;测试: 内存列表) + protected virtual List FindTradeExtends(List tradeIds) + { + return DbContext.trade_extend.Where(x => tradeIds.Contains(x.TradeId)).ToList(); + } + + /// 查找指定日期的日终汇总(生产: DbContext.eod_swap;测试: 内存列表) + protected virtual List FindEodSwapsByDate(DateTime valueDate) + { + return DbContext.eod_swap.Where(x => x.ValueDate == valueDate).ToList(); + } + + /// 查找交易在指定日期的完成流水事件(生产: DbContext.swap_flow_event;测试: 内存列表) + protected virtual List FindFlowEvents(int swapTradeId, DateTime settleDate) + { + Expression> eventExpression = x => x.SwapTradeId == swapTradeId + && x.DataState == (int)SwapFlowDateStateEnum.完成 + && x.EventDate == settleDate; + return DbContext.swap_flow_event.Where(eventExpression).ToList(); + } + #endregion /// @@ -205,28 +250,17 @@ namespace YLErp.Modules.SwapModule { var dateStr = settleDate.ToString("yyyy-MM-dd"); Log.Info("SwapPositionCompose:" + "settleDate:" + settleDate + " preSettleDate:" + preSettleDate + " ClientIds:" + JsonHelper.Serialize(ClientIds)); - var tradePredicate = PredicateBuilder.Create(n => n.ValidState != ConsGlobal.InValid - && n.TradeType == "收益互换" - && n.TradeDate <= settleDate - && n.ExerciseDate >= settleDate - && (n.TradeStatus == ConsTrade.确认成交 || n.UnWindDate >= settleDate) - ); - if (ClientIds != null && ClientIds.Any()) - { - tradePredicate = tradePredicate.And(x => ClientIds.Contains(x.ClientId)); - } - var tradeQueryList = DbContext.trade.Where(tradePredicate).ToList(); + var tradeQueryList = FindActiveSwapTrades(settleDate, ClientIds); var tradeIds = tradeQueryList.Select(s => s.id).ToList(); - var allTradePositionList = DbContext.swap_position.Where(t => tradeIds.Contains(t.SwapTradeId) && !t.Invalid).ToList(); + var allTradePositionList = FindAllSwapPositions(tradeIds); var tradePositionList = allTradePositionList.Where(t => t.IsInitial).ToList(); var tradeRealPositionList = allTradePositionList.Where(t => !t.IsInitial).ToList(); - var tradeExtendList = DbContext.trade_extend.Where(x => tradeIds.Contains(x.TradeId)).ToList(); - var eodSwapList = DbContext.eod_swap.Where(x => x.ValueDate == preSettleDate).ToList(); + var tradeExtendList = FindTradeExtends(tradeIds); + var eodSwapList = FindEodSwapsByDate(preSettleDate); List eventTyps = new List() { (int)SwapEventTypeEnum.平仓, (int)SwapEventTypeEnum.互换, (int)SwapEventTypeEnum.自动互换 }; foreach (var td in tradeQueryList) { - var trans = DbContext.Database.BeginTransaction(); - try + ExecuteInTransaction(() => { List removeEventTyps = new List() { (int)SwapEventTypeEnum.自动互换 }; bool longShort = td.StructureType == ClientMarginTypeEnum.多空组合.ToString(); @@ -243,7 +277,7 @@ namespace YLErp.Modules.SwapModule { throw new Exception($"交易{td.TradeNumber}在上一交易日【{preSettleDate:yyyy-MM-dd}】未收盘"); } - var allEodPositions = DbContext.eod_swap_position.Where(x => x.ValueDate >= preSettleDate && x.SwapTradeId == td.id && !x.Invalid); + var allEodPositions = FindEodSwapPositions(td.id, preSettleDate); var eodPositions = allEodPositions.Where(x => x.ValueDate == preSettleDate).ToList();//上一日终持仓信息 @@ -256,18 +290,7 @@ namespace YLErp.Modules.SwapModule { throw new Exception($"交易【{td.TradeNumber}】到期扔有持仓信息"); } - var flowEvents = new List(); - Expression> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum.完成; - eventExpression = eventExpression.And(x => x.EventDate == settleDate); - //if (settleDate == td.TradeDate) - //{ - // eventExpression = eventExpression.And(x => x.EventDate == settleDate); - //} - //else - //{ - // eventExpression = eventExpression.And(x => x.UnwindDate == settleDate); - //} - flowEvents = DbContext.swap_flow_event.Where(eventExpression).ToList(); + var flowEvents = FindFlowEvents(td.id, settleDate); var preDealDate = GetPreDealDate(td.id, settleDate, eventTyps);//上一次平仓/互换/自动互换处理日期 List autoInterests = new List();//自动互换利息腿信息 //处理浮动腿 @@ -296,18 +319,8 @@ namespace YLErp.Modules.SwapModule td.TradeStatus = "已到期"; td.UnWindDate = settleDate; } - DbContext.SaveChanges(); - trans.Commit(); - } - catch (Exception ex) - { - trans.Rollback(); - throw new Exception(ex.Message, ex); - } - finally - { - trans.Dispose(); - } + SaveAllChanges(); + }); } }