From 75988a33ebe5d1154567e6958997f74dd6b3f7ca Mon Sep 17 00:00:00 2001 From: hjhan Date: Fri, 17 Jul 2026 10:32:57 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20eod=5Fcommodity=5Ffuture=5Fprice=20?= =?UTF-8?q?=E5=85=A5=E5=BA=93=E5=89=8D=E4=BB=A5=20UnderlyingCode=20?= =?UTF-8?q?=E9=87=8D=E6=B4=BE=E7=94=9F=20UnderlyingId=EF=BC=8C=E9=98=B2?= =?UTF-8?q?=E6=AD=A2=20FR007=20=E7=AD=89=E4=BB=B7=E6=A0=BC=E8=A1=8C=20Unde?= =?UTF-8?q?rlyingId=20=E4=B8=8E=20FutureContractId=20=E5=A4=B1=E5=90=8C?= =?UTF-8?q?=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 EodPriceService.SyncUnderlyingIdFromCode:入库前以 UnderlyingCode(FutureContractId) 为准反查真实 UnderlyingId,不一致则告警并自动校正 - SaveEodFuturePrice(web编辑/新增)、SettlementPriceImportService(xlsx上传)、EodSyntheticPriceSaveService(系统合成价) 写入前调用 - 根治'网页端能查到、EOD结算查不到'的失同步问题 --- YLErpDAL/Modules/EodModule/EodPriceService.cs | 39 +++++++++++++++++-- .../EodSyntheticPriceSaveService.cs | 3 ++ .../EodModule/SettlementPriceImportService.cs | 2 + 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/YLErpDAL/Modules/EodModule/EodPriceService.cs b/YLErpDAL/Modules/EodModule/EodPriceService.cs index d23415b3..ce2ced60 100644 --- a/YLErpDAL/Modules/EodModule/EodPriceService.cs +++ b/YLErpDAL/Modules/EodModule/EodPriceService.cs @@ -1,8 +1,5 @@ -using System.Collections.Generic; -using System.Linq; using BaseOUDAL; -using DocumentFormat.OpenXml.Bibliography; -using NPOI.POIFS.NIO; +using YLErp.BLL; using YLErp.Helpers; namespace YLErp.Modules.EodModule @@ -32,6 +29,37 @@ namespace YLErp.Modules.EodModule return (start, end); } + /// + /// 校正 eod_commodity_future_price 行的 UnderlyingId,使其与 UnderlyingCode(=FutureContractId) 一致。 + /// 背景:网页日终价格列表按 UnderlyingId(int) JOIN underlying_manager,而 EOD 结算(EodPriceProvider.Initialize) + /// 按 UnderlyingCode(string) JOIN。两列一旦失同步(典型如 FR007 的价格行 UnderlyingId 被错写成 511160.SH 的 id), + /// 会出现"网页能查到、结算却查不到"的错价缺失,进而 EodCheckSettlePrice 报"结算价格缺失"。 + /// 这里以 UnderlyingCode 为准重新派生 UnderlyingId——该列才是上传/结算使用的自然键(FutureContractId), + /// 在入库前强制两列一致,既阻止产生新的错行,又通过告警日志把失同步暴露给运维追查上游写入来源。 + /// + public static void SyncUnderlyingIdFromCode(YLContext db, eod_commodity_future_price row) + { + if (row == null || string.IsNullOrWhiteSpace(row.UnderlyingCode)) + { + return; + } + + var um = db.underlying_manager.FirstOrDefault(u => u.UnderlyingCode == row.UnderlyingCode); + if (um == null) + { + // 标的代码在 underlying_manager 不存在:无法校正,交由既有"标的代码不存在"等校验处理。 + return; + } + + if (row.UnderlyingId != um.id) + { + LogFactory.GetLogger("EodPrice").Info( + $"eod_commodity_future_price.UnderlyingId 与 UnderlyingCode 不一致,已自动校正: " + + $"FutureContractId={row.UnderlyingCode}, 原UnderlyingId={row.UnderlyingId}, 修正为={um.id}"); + row.UnderlyingId = um.id; + } + } + public SearchListResult SearchUnderlyingList(EodCommodityFuturePriceReq req) { var (valueDtStart, valueDtEnd) = ResolveValueDateWindow(req.ValueDateStart, req.ValueDateEnd); @@ -219,6 +247,9 @@ namespace YLErp.Modules.EodModule dbmodel.DataSource = EodPriceBase.人工; + // 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。 + SyncUnderlyingIdFromCode(DbContext, dbmodel); + DbContext.SaveChanges(); return dbmodel; diff --git a/YLErpDAL/Modules/EodModule/SettlementModule/EodSyntheticPriceSaveService.cs b/YLErpDAL/Modules/EodModule/SettlementModule/EodSyntheticPriceSaveService.cs index d086b8bf..aac67efa 100644 --- a/YLErpDAL/Modules/EodModule/SettlementModule/EodSyntheticPriceSaveService.cs +++ b/YLErpDAL/Modules/EodModule/SettlementModule/EodSyntheticPriceSaveService.cs @@ -159,6 +159,9 @@ namespace YLErp.Modules.EodModule.SettlementModule DataSource = EodPriceBase.系统 }; + // 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。 + EodPriceService.SyncUnderlyingIdFromCode(DbContext, dto.CommodityPrice); + DbContext.eod_commodity_future_price.Add(dto.CommodityPrice); } diff --git a/YLErpDAL/Modules/EodModule/SettlementPriceImportService.cs b/YLErpDAL/Modules/EodModule/SettlementPriceImportService.cs index 59e69bd2..594edcb4 100644 --- a/YLErpDAL/Modules/EodModule/SettlementPriceImportService.cs +++ b/YLErpDAL/Modules/EodModule/SettlementPriceImportService.cs @@ -158,6 +158,8 @@ namespace YLErp.Modules.EodModule eodPrice.ValueDate = item.date; eodPrice.UnderlyingCode = underlying.UnderlyingCode; eodPrice.UnderlyingId = underlying.id; + // 入库前强制 UnderlyingId 与 UnderlyingCode(FutureContractId) 一致,避免网页/结算两套 JOIN 失同步。 + EodPriceService.SyncUnderlyingIdFromCode(DbContext, eodPrice); if (item.closePrice.HasValue) eodPrice.ClosePrice = item.closePrice ?? 0; if (item.settlePrice.HasValue)