diff --git a/YLErpDAL/Modules/UnderlyingModule/UnderlyingHelper.cs b/YLErpDAL/Modules/UnderlyingModule/UnderlyingHelper.cs index 52c55e39..76de199c 100644 --- a/YLErpDAL/Modules/UnderlyingModule/UnderlyingHelper.cs +++ b/YLErpDAL/Modules/UnderlyingModule/UnderlyingHelper.cs @@ -306,6 +306,13 @@ namespace YLErp.Modules.UnderlyingModule double yearTerm = (totalMonths + fractionalMonth) / 12.0; return yearTerm; } + /// + /// 期限计算异常提示去重:同一标的只提示一次。此前用 Console.WriteLine 直打控制台, + /// 已到期标的在预付金模板取率热路径(MarginTemplateV2RateHelper)每次调用都抛 + /// "计算日期必须小于原日期",造成管理端刷屏。 + /// + private static readonly System.Collections.Concurrent.ConcurrentDictionary _termWarnedUnderlyings = new(); + /// /// 根据标的发行年限和剩余期限计算适用保证金率 /// 规则表格: @@ -332,18 +339,24 @@ namespace YLErp.Modules.UnderlyingModule { // 获取标的信息 var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(underlyingCode); - if (underlying == null || !underlying.MaturityDate.HasValue) + if (underlying == null || !underlying.MaturityDate.HasValue) return ConsMarginTerm.UnderFiveYear; - // 计算剩余期限(从估值日期到到期日期) - var remainingTermYears = getYearTerm(valueDate, underlying.MaturityDate); + // 已到期标的(到期日≤估值日):剩余期限按 0 计,直接走期限档规则(≤5年→默认档), + // 不再进 getYearTerm——其对 calcDate>sourceDate 抛"计算日期必须小于原日期",是此前高频日志的来源 + var remainingTermYears = underlying.MaturityDate.Value <= valueDate + ? 0 + : getYearTerm(valueDate, underlying.MaturityDate); // 根据业务规则确定适用的保证金率期限 return DetermineMarginTerm(remainingTermYears); } catch (Exception ex) { - // 记录异常日志 - Console.WriteLine($"计算保证金率期限时发生异常: {ex.Message}"); + //兜底:按默认档(<5y)返回,取率不中断;同一标的只提示一次防刷屏 + if (_termWarnedUnderlyings.TryAdd(underlyingCode, 0)) + { + LogFactory.GetLogger("计算保证金率期限").Info($"【警告】标的{underlyingCode}计算保证金率期限发生异常,按默认档(<5y)兜底:{ex.Message}"); + } return ConsMarginTerm.UnderFiveYear; } }