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}";
+ }
+ }
+}