From 003323d678e17841eb2d817038149a28a9dd57ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=AC=E5=86=B0=E5=86=B0?= <437394478@qq.com> Date: Wed, 26 Aug 2026 10:50:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20C#=20=E7=AE=A1=E7=90=86=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E9=85=8D=E7=BD=AE=E7=9A=84=E9=82=AE=E4=BB=B6=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF-=E7=BC=BA=E5=B0=91=E5=8F=98=E9=87=8F=E5=8F=82?= =?UTF-8?q?=E6=95=B0=EF=BC=9A=E4=BA=A4=E6=98=93=E7=BC=96=E5=8F=B7=E3=80=81?= =?UTF-8?q?=E5=B9=B3=E4=BB=93=E6=80=BB=E9=A2=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SettlementMailTemplateHelper.cs | 107 ++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 YLErpDAL/Modules/ReportModule/SettlementMailTemplateHelper.cs diff --git a/YLErpDAL/Modules/ReportModule/SettlementMailTemplateHelper.cs b/YLErpDAL/Modules/ReportModule/SettlementMailTemplateHelper.cs new file mode 100644 index 00000000..45edfdf4 --- /dev/null +++ b/YLErpDAL/Modules/ReportModule/SettlementMailTemplateHelper.cs @@ -0,0 +1,107 @@ +using System.Globalization; +using Microsoft.EntityFrameworkCore; +using YLErp.BLL; +using YLErp.Modules.AppModule; + +namespace YLErp.Modules.ReportModule +{ + /// + /// 为结算确认书邮件准备交易编号和平仓总额模板变量。 + /// + public static class SettlementMailTemplateHelper + { + /// + /// 根据当前客户的确认书反查对应交易和平仓记录。 + /// 文档编号可能在不同文档类型中重复,因此必须同时匹配编号和类型。 + /// + public static List GetSettlementRows(YLContext dbContext, IEnumerable documents, int clientId) + { + var documentKeys = documents + .Where(document => !string.IsNullOrWhiteSpace(document.Code)) + .Select(document => BuildDocumentKey(document.Code, document.Type)) + .Distinct() + .ToHashSet(); + + if (documentKeys.Count == 0) + { + return new List(); + } + + var contractCodes = documents.Select(document => document.Code).Distinct().ToList(); + var rows = (from relation in dbContext.trade_contract_r + join tradeCash in dbContext.trade_cash on relation.TradeCashId equals tradeCash.id + join tradeData in dbContext.trade on tradeCash.TradeId equals tradeData.id + where contractCodes.Contains(relation.ContractCode) + && relation.IsValid + && !tradeCash.IsDeleted + && tradeData.ClientId == clientId + select new + { + relation.ContractCode, + relation.Type, + Trade = tradeData, + TradeCash = tradeCash + }).AsNoTracking().ToList(); + + return rows + // 数据库先按编号缩小范围,再在内存中用“编号+类型”精确匹配附件。 + .Where(row => documentKeys.Contains(BuildDocumentKey(row.ContractCode, row.Type))) + .Select(row => new Datas + { + trade = row.Trade, + tradecash = row.TradeCash + }).ToList(); + } + + /// + /// 将批量加载的数据限制到当前结算日,避免跨日发送时变量汇总串日。 + /// + public static List ForValueDate(IEnumerable rows, DateTime valueDate) + { + return (rows ?? Enumerable.Empty()) + .Where(row => row?.tradecash != null && row.tradecash.ValueDate.Date == valueDate.Date) + .ToList(); + } + + /// + /// 将去重后的交易编号及客户视角平仓总额写入邮件模板参数。 + /// + public static void PopulateSettlementFields(MailInfoRequestModel request, IEnumerable rows) + { + ArgumentNullException.ThrowIfNull(request); + + // 同一平仓记录可能因关联多份文档重复出现,按 trade_cash.id 去重以避免重复计入金额。 + var distinctRows = (rows ?? Enumerable.Empty()) + .Where(row => row?.trade != null && row.tradecash != null) + .GroupBy(row => row.tradecash.id) + .Select(group => group.First()) + .ToList(); + + request.TradeNumber = string.Join(",", distinctRows + .Select(row => row.trade.TradeNumber) + .Where(number => !string.IsNullOrWhiteSpace(number)) + .Distinct() + .OrderBy(number => number)); + + if (distinctRows.Count == 0) + { + request.UnwindTotalAmount = string.Empty; + return; + } + + // trade_cash.Amount 为交易员视角,邮件展示需取反转换为客户视角。 + var customerAmount = -distinctRows.Sum(row => row.tradecash.Amount); + if (customerAmount == 0) + { + // 消除浮点求和可能产生的 -0.00。 + customerAmount = 0; + } + request.UnwindTotalAmount = customerAmount.ToString("F2", CultureInfo.InvariantCulture); + } + + private static string BuildDocumentKey(string code, string type) + { + return $"{code}\u001f{type}"; + } + } +}