Files
zszq-trs/YLErpWeb/Controllers/eod_trade_valueController.cs
2025-08-13 17:27:42 +08:00

825 lines
32 KiB
C#

using Microsoft.AspNetCore.Authorization;
using System.Collections.Concurrent;
using System.Threading;
using YLErp.BLL.Eod;
using YLErp.DBModels;
using YLErp.Model.Enum;
using YLErp.Modules.ClientModule;
using YLErp.Modules.EodModule;
using YLErp.Modules.EodModule.QueryModule;
using YLErp.Modules.EodModule.SettlementModule;
using YLErp.Modules.FinancialModule;
using YLErp.Modules.TradeModule.DealModule;
using YLErp.Office;
using YLErp.QdpModule;
namespace YLErp.Web.Controllers
{
public class eod_trade_valueController : BaseController
{
[MyAuthorize("结算管理-收盘操作")]
public ActionResult eodExec()
{
var config = PS.Config.GetSettlementConfig();
ViewData["EodHistory"] = GetEodHistoryData(null, 5);
return View("eodExecV2", config);
}
public Result SendMaturityEmail(DateTime settleDate)
{
var maturityDate = settleDate;
var a = 0;
//获取之后三个交易日
for (var i = 0; i < 3;)
{
a++;
maturityDate = maturityDate.AddDays(1);
if (!QdpCalendarHelper.IsHoliday(maturityDate))
{
i++;
}
else
{
continue;
}
if (a >= 20)
{
throw new Exception("日历记录异常," + settleDate.ToString("yyyy-MM-dd") + "后未查找到有效的3个交易日!");
};
}
//获取交易
var query = (from trade in yldb.trade where trade.TradeStatus == "确认成交" && trade.ValidState != "InValid" && trade.ClientId != 0 && trade.MaturityDate > settleDate && trade.MaturityDate <= maturityDate select trade);
var tradeList = query.ToList();
if (tradeList != null && tradeList.Count > 0)
{
var clientIds = tradeList.Select(t => t.ClientId).ToList();
var clientList = ClientDataQueryService.GetClientsFromDB(t => clientIds.Contains(t.id));
if (clientList != null)
{
var errorClientList = new List<string>();
var errorMsg = new List<string>();
foreach (var client in clientList)
{
var clientTradeList = tradeList.Where(t => t.ClientId == client.id).ToList();
var bodyhtml = string.Empty;
bodyhtml += "<meta http-equiv='Content-Type' content='text/html;charset=utf-8'/>";
bodyhtml += $"<p><h1>近期到期交易列表</h1></p>";
bodyhtml += $"<p><h2>客户名称:{client.Name}</h2></p>";
bodyhtml += $"<p><h2>日期:{settleDate:yyyy-MM-dd}</h2></p>";
bodyhtml += "<table border='1'>";
bodyhtml += "<tr>";
bodyhtml += " <th> 交易编号</th>";
bodyhtml += " <th> 交易日期</th>";
bodyhtml += " <th> 交易方向 </th>";
bodyhtml += " <th> 标的代码 </th>";
bodyhtml += " <th> 结构类型</th>";
bodyhtml += " <th> 看涨看跌</th>";
bodyhtml += " <th> 行权方式</th>";
bodyhtml += " <th> 到期日</th>";
bodyhtml += " <th> 行权价</th>";
bodyhtml += " </tr>";
foreach (var trade in clientTradeList)
{
bodyhtml += " <tr>";
bodyhtml += $" <td>{trade.TradeNumber}</td>";
bodyhtml += $" <td>{(trade.TradeDate == null ? "" : trade.TradeDate.Value.ToString("yyyy-MM-dd")):F}</td>";
bodyhtml += $" <td>{trade.BuySell}</td>";
bodyhtml += $" <td>{trade.UnderlyingCode}</td>";
bodyhtml += $" <td>{trade.TradeType:F}</td>";
bodyhtml += $" <td>{("Call".Equals(trade.CallPut) ? "看涨" : "看跌")}</td>";
bodyhtml += $" <td>{trade.ExerciseModeCn:F}</td>";
bodyhtml += $" <td>{(trade.ExerciseDate == null ? "" : trade.ExerciseDate.Value.ToString("yyyy-MM-dd"))}</td>";
//股票类期权 行权价给实际行权价
if (trade.IsMoneynessOptionData)
{
bodyhtml += $" <td>{trade.Strike * (trade.SpotPrice ?? 0):F}</td>";
}
else
{
bodyhtml += $" <td>{trade.Strike:F}</td>";
}
bodyhtml += " </tr>";
}
bodyhtml += "</table>";
// 要向该客户的所有订阅了邮件通知的人员发送邮件
//var clientContactMails = db.clientduty.Where(x => x.ClientId == client.id && x.IsReceiveEmail.HasValue && x.IsReceiveEmail == 1).Select(x => x.Email).ToList();
var emails = ClientDataQueryService.GetClientEmails(client.id, false);
if (emails != null & emails.Any())
{
var sendMail = EmailHelper.SendMail(string.Join(";", emails), "近期到期交易列表", bodyhtml, true, null);
if (!string.IsNullOrEmpty(sendMail))
{
errorClientList.Add(client.Name);
if (!errorMsg.Contains(sendMail))
{
errorMsg.Add(sendMail);
}
}
}
}
//判断是否有发送失败的客户
if (errorClientList.Count > 0)
{
var msg = $"错误:{string.Join(",", errorClientList.ToArray())}发送报告时出错,{string.Join(",", errorMsg.ToArray())}。";
return new Result { success = false, msg = msg };
}
}
}
return new Result { success = false, msg = "发送客户" + settleDate.ToString("yyyy年MM月dd日") + "近期到期交易报告成功。" };
}
/// <summary>
/// 财务凭证
/// </summary>
public ActionResult FinancialStatements()
{
return View();
}
/// <summary>
///
/// </summary>
public ActionResult FinancialStatementsQuery(FinancialStatementReq req)
{
var bll = new FinancialVoucherService(CurUser);
if (req == null)
{
return JsonError("请求实体不能为空");
}
var returnInfo = bll.GetFinancialStatements(req);
if (!returnInfo.Success)
{
return JsonError(returnInfo.Msg);
}
if (string.IsNullOrWhiteSpace(req.sidx))
{
returnInfo.Content = returnInfo.Content.OrderBy(f => f.AbstractTye).ToList();
}
var searchListResult = returnInfo.Content.AsQueryable().ToSearchList(req);
return Json(searchListResult);
}
/// <summary>
///
/// </summary>
/// <param name="req"></param>
/// <param name="exportType">0:导出当前,1:导出同业,2:导出非同业</param>
/// <returns></returns>
public FileStreamResult ExportFinancialVoucher(FinancialStatementReq req, int exportType = 0)
{
if (exportType < 0 || exportType > 2)
{
return null;
}
if (req == null)
{
req = new FinancialStatementReq();
}
var bll = new FinancialVoucherService(CurUser);
if (exportType == 1)
{
req.IsSamePeer = SamePeerEnum.IsSamePeer.GetHashCode();
req.AbstractList = null;
}
else if (exportType == 2)
{
req.IsSamePeer = SamePeerEnum.NotSamePeer.GetHashCode();
req.AbstractList = null;
}
var returnInfo = bll.GetFinancialStatements(req);
if (!returnInfo.Success)
{
return null;
}
if (returnInfo.Content == null || returnInfo.Content.Count == 0)
{
return null;
}
if (exportType == 0)
{
var fileDownloadName = $"场外期权财务凭证_{DateTime.Now:yyyyMMdd}.xlsx";
var excelReturn = returnInfo.Content.ListToExcel2(new Dictionary<string, string>
{
{"摘要", "Abstract"},
{"同业/非同业", "IsSamePeerDesc"},
{"借贷方向", "Children.DebitOrCreditDesc"},
{"会计科目", "Children.AccountingSubject"},
{"辅助核算单位", "Children.SupplementaryAcountingUnit"},
{"数据字段", "Children.DataField"},
{"备注", "Children.Remark"}
});
return File(new FileStream(excelReturn.FileName, FileMode.Open),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileDownloadName);
}
if (exportType == 1 || exportType == 2)
{
var fileDownloadName = $"场外期权财务凭证{(exportType == 1 ? "(同业)" : "(非同业)")}_{DateTime.Now:yyyyMMdd}.xlsx";
var group = returnInfo.Content.GroupBy(f => f.AbstractTye).OrderBy(g => g.Key)
.ToDictionary(g => EnumHelper.GetDescriptionByName((FinancialVoucherAbstractEnum)g.Key),
g => g.ToList());
var excelReturn = group.GroupToExcel2(new Dictionary<string, string>
{
{"摘要", "Abstract"},
{"同业/非同业", "IsSamePeerDesc"},
{"借贷方向", "Children.DebitOrCreditDesc"},
{"会计科目", "Children.AccountingSubject"},
{"辅助核算单位", "Children.SupplementaryAcountingUnit"},
{"数据字段", "Children.DataField"},
{"备注", "Children.Remark"}
});
return File(new FileStream(excelReturn.FileName, FileMode.Open),
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileDownloadName);
}
return null;
}
#region----收盘历史----
/// <summary>
/// 收盘历史
/// </summary>
public ActionResult EodHistory(int? year)
{
var datas = GetEodHistoryData(year);
return View(datas);
}
private IEnumerable<EodStatus> GetEodHistoryData(int? year, int maxRows = 0)
{
var today = DateTime.Today;
if (year == null || year < 1 || year > 3000)
{
year = today.Year;
}
var startDate = new DateTime(year.Value, 1, 1);
var endDate = new DateTime(year.Value, 12, 31);
var allEodStatus = new EodStatus[400];
var hasExtendVol = SettlementViewModel.HasExtendVol();
var dbQuery = yldb.eodStatus.Where(n => n.ValueDate >= startDate && n.ValueDate <= endDate);
if (maxRows > 0)
{
dbQuery = dbQuery.OrderByDescending(n => n.ValueDate).Take(maxRows);
}
var dbDatas = dbQuery.ToArray();
foreach (var data in dbDatas)
{
allEodStatus[data.ValueDate.DayOfYear] = data;
if (!hasExtendVol)
{
data.VolTypeFlag = (data.VolTypeFlag | VolTypeFlagEnum.ExtendVol) ^ VolTypeFlagEnum.ExtendVol;
data.VolTypeFlag_S = (data.VolTypeFlag_S | VolTypeFlagEnum.ExtendVol) ^ VolTypeFlagEnum.ExtendVol;
}
}
while (startDate <= endDate && startDate <= today)
{
if (!BLL.valuedateBLL.IsHoliday(startDate) && allEodStatus[startDate.DayOfYear] == null)
{
allEodStatus[startDate.DayOfYear] = new EodStatus { ValueDate = startDate, Status = "未执行" };
}
startDate = startDate.AddDays(1);
}
var retQuery = allEodStatus.Where(n => n != null).Reverse();
if (maxRows > 0)
{
retQuery = retQuery.Take(maxRows);
}
return retQuery.ToArray();
}
/// <summary>
/// 修改收盘数据核对状态
/// </summary>
[MyAuthorize("结算管理-收盘数据核对")]
public JsonResult UpdateCheckStatus(string encryptId)
{
try
{
var intid = DecryptInt(encryptId);
var eodstatus = yldb.eodStatus.Find(intid);
if (eodstatus.Status != "已收盘")
{
return JsonSuccess("未收盘");
}
eodstatus.CheckStatus = true;
eodstatus.CheckDate = DateTime.Now;
if (PS.Config.Is润和)
{
new DongZhengEodTradePositionExportService(CurUser).ExportDongZhengZipFile(eodstatus.ValueDate);
}
yldb.SaveChanges();
return JsonSuccess("核对状态修改成功");
}
catch (Exception ex)
{
return JsonError("执行失败:" + ex.Message);
}
}
#endregion
#region----eodExecV2----
/// <summary>
/// 保存收盘请求
/// </summary>
public JsonResult AjaxSaveEodTask(EodTaskSaveReq req, bool isDebug = false)
{
var debugging = isDebug && System.Diagnostics.Debugger.IsAttached;
if (!string.IsNullOrEmpty(req.DividendRateTypes)&&req.DividendRateTypes.Contains("采集"))
{
req.VolTypes += ",分红率0";
}
var task = new EodTaskSaveService(CurUser).SaveData(req, !debugging);
if (debugging)
{
EodTaskRunner.ExecuteDebugAsync(task);
}
return JsonSuccess();
}
/// <summary>
/// 取消收盘任务
/// </summary>
public JsonResult AjaxCancelEodTask(int taskId)
{
new EodTaskSaveService(CurUser).CancelTask(taskId);
return JsonSuccess();
}
/// <summary>
/// 继续执行/重新执行
/// </summary>
public JsonResult AjaxRestartEodTask(int taskId, bool resetAll = true, bool isDelayTrade = false)
{
new EodTaskSaveService(CurUser).RestartTask(taskId, resetAll, isDelayTrade);
return JsonSuccess();
}
/// <summary>
/// 收盘任务报告
/// </summary>
public ActionResult AjaxGetTaskRunReport(bool firstTask = true)
{
var datas = new EodTaskQueryService(CurUser).GetEodTasksToShow(firstTask);
return PartialView("_eodTaskDetail", datas);
}
/// <summary>
/// 收盘历史
/// </summary>
public ActionResult AjaxGetEodHistoryTable()
{
var datas = GetEodHistoryData(null, 5);
return PartialView("_EodHistoryTable", datas);
}
/// <summary>
/// 执行汇率检查
/// </summary>
public JsonResult AjaxCheckCurrencyRae(DateTime date)
{
var result = new EodCurrencyRateService(CurUser).CheckEodCurrencyRateMissing(date);
return JsonSuccessData(result);
}
/// <summary>
/// 复制上日汇率
/// </summary>
public JsonResult AjaxCopyPreCurrencyRae(DateTime date)
{
var service = new EodCurrencyRateService(CurUser);
var changes = service.CopyPreCurrencyRate(date, out var preDate);
var result = service.CheckEodCurrencyRateMissing(date);
var resultMsg = $"目标日期'{date:yyyy-MM-dd}',上日日期:'{preDate:yyyy-MM-dd}',复制{changes}条,";
if (!string.IsNullOrEmpty(result.Error))
{
resultMsg += "重新检查后报错:" + result.Error;
}
if (result.HasMissing)
{
resultMsg += "重新检查后仍然缺失";
}
else
{
resultMsg += "重新检查后未缺失汇率";
}
return JsonSuccessData(new { result, resultMsg });
}
public object AjaxCheckSettlePrice(DateTime dateStart, DateTime dateEnd)
{
var NoPriceUnderlyings = new List<KeyValuePair<string, string>>();
var start = new DateTime(dateStart.Ticks);
while (dateEnd >= dateStart)
{
var umCodes = new EodCheckPriceService(CurUser).GetNoPriceUnderlyings(dateStart);
if (umCodes != null && umCodes.Count > 0)
{
foreach (var code in umCodes)
{
NoPriceUnderlyings.Add(new KeyValuePair<string, string>(dateStart.ToString("yyyy-MM-dd"), code));
}
}
dateStart = dateStart.AddDays(1);
}
//if (NoPriceUnderlyings.Count == 0)
//{
// return Json("价格无缺失");
//}
var bytes = new EodCheckPriceService(CurUser).exportNoPriceUnderlyings(NoPriceUnderlyings);
return File(bytes, xlsxMimeType, $"收盘价格缺失{start:yyyyMMdd}-{dateEnd:yyyyMMdd}.xlsx");
}
/// <summary>
/// 执行期权观察状态
/// </summary>
public JsonResult AjaxSaveEodKnowInOut(EodTaskSaveReq req, bool isDebug = false)
{
try
{
List<DateTime> dts = QdpCalendarHelper.AllBizDays(req.StartDate, req.EndDate.AddDays(1));
foreach (var item in dts)
{
new Modules.EodModule.SettlementModule.EodCheckMonitoredTradeSingle(CurUser).ExecuteTask(item, req.ClientIds);
}
return JsonSuccess("执行成功");
}
catch (Exception ex)
{
return JsonError("执行失败:" + ex.Message);
}
}
/// <summary>
/// 检察当日异常标的
/// </summary>
public JsonResult AjaxCheckExerciseTradeUnderly(bool update = false)
{
if (!update)
{
var exerciseTradeUnderly = new TradeDelaySettlementService(CurUser).GetCacheExerciseTradeUnderly();
return JsonSuccess("", exerciseTradeUnderly);
}
else
{
var exerciseTradeUnderly = new TradeDelaySettlementService(CurUser).CheckExerciseTradeUnderly();
return JsonSuccess("", exerciseTradeUnderly);
}
}
/// <summary>
/// 检察收盘时有需要延期的交易
/// </summary>
/// <returns></returns>
public JsonResult AjaxCheckEodExerciseTradeUnderly(DateTime dateStart, DateTime dateEnd)
{
bool isHaveDelayTrade = false;
string msg = "";
//只有当天收盘
if (dateStart == dateEnd && dateEnd == valuedateBLL.ValueDate)
{
var updownUnderly = new TradeDelaySettlementService(CurUser).GetDelayUnderlyIds(dateStart);
if (updownUnderly.Any())
{
isHaveDelayTrade = true;
msg = new TradeDelaySettlementService(CurUser).GetDelayTradeNumber(updownUnderly.ToList());
}
}
//其他
else
{
while (dateEnd >= dateStart)
{
var updownUnderly = new TradeDelaySettlementService(CurUser).GetDelayUnderlyIds(dateStart);
if (updownUnderly.Any())
{
isHaveDelayTrade = true;
break;
}
dateStart = dateStart.AddDays(1);
}
}
return JsonSuccess("成功", new { isHaveDelayTrade, msg });
}
/// <summary>
/// 继续执行/重新执行
/// </summary>
public JsonResult AjaxCheckRestartEodTaskTradeUnderly(int taskId)
{
var task = YLErp.Modules.DbContextFactory.GetYLDbContext().EodTask.FirstOrDefault(n => n.id == taskId);
if (task == null)
{
throw new ServiceException("任务数据已不存在");
}
switch (task.TaskState)
{
case EodTaskState.completed:
case EodTaskState.failure:
case EodTaskState.canceled:
case EodTaskState.interrupted: break;
case EodTaskState.running:
if (EodTaskRunner.LastTask?.id == taskId)
{
throw new ServiceException("任务正在运行中");
}
break;
default: throw new ServiceException("不符合重新执行的条件,任务当前状态:" + EodTaskHelper.GetEodTaskStateDesc(task.TaskState));
}
bool isHaveDelayTrade = false;
string msg = "";
DateTime dateStart = task.StartDate, dateEnd = task.EndDate;
//只有当天收盘
if (dateStart == dateEnd && dateEnd == valuedateBLL.ValueDate)
{
var updownUnderly = new TradeDelaySettlementService(CurUser).GetDelayUnderlyIds(dateStart);
if (updownUnderly.Any())
{
isHaveDelayTrade = true;
msg = new TradeDelaySettlementService(CurUser).GetDelayTradeNumber(updownUnderly.ToList());
}
}
//其他
else
{
while (dateEnd >= dateStart)
{
var updownUnderly = new TradeDelaySettlementService(CurUser).GetDelayUnderlyIds(dateStart);
if (updownUnderly.Any())
{
isHaveDelayTrade = true;
break;
}
dateStart = dateStart.AddDays(1);
}
}
return JsonSuccess("成功", new { isHaveDelayTrade, msg });
}
#endregion
#region 互换持仓明细导入
public ActionResult eodTradeSwapMannual()
{
return View();
}
/// <summary>
/// 导入互换交易
/// </summary>
public ActionResult UploadEodTradeSwapMannual()
{
if (Request.Form.Files.Count == 0)
{
return JsonError("上传文件不存在");
}
var file = Request.Form.Files[0];
if (!Path.GetExtension(file.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
{
return JsonError("请上传Excel(.xlsx)格式文件");
}
DateTime valuedate = Convert.ToDateTime(Request.Form["ValueDate"]);
using var inputStream = file.OpenReadStream();
new EodSwapPositionMannualImportService(CurUser).ImportEodSwapPositionMannualFromExcel(inputStream, valuedate, out var TotalNum, out var SuccessNum);
return Json(new
{
success = true,
totalNum = TotalNum,
successNum = SuccessNum,
});
}
#endregion
#region 历史标的交易收盘
[HttpGet]
[AllowAnonymous]
public JsonResult ExecuteEodPositionSettle()
{
try
{
string volType = "持仓";
bool useClosePrice = true;
// 1. 创建用户信息对象
var userInfo = OptUserInfo.SystemUser;
// 2. 获取 exchange_trade 表的最早和最晚交易日期
var valueDate = valuedateBLL.ValueDate;
var earliestTradeDate = yldb.ExchangeTrade.Where(et => et.IsValid)
.Min(et => (DateTime?)et.TradeDate) ?? valueDate;
var latestTradeDate = EodOperationBase.GetLastSettlementDate(valueDate);
// 计算预计处理的交易日数量
var estimatedDays = 0;
var tempDate = earliestTradeDate;
while (tempDate <= latestTradeDate)
{
estimatedDays++;
tempDate = BLL.valuedateBLL.GetNonHoliday(tempDate.AddDays(1));
}
// 3. 异步执行结算任务
var taskId = Guid.NewGuid().ToString();
// 初始化任务状态
var cancellationTokenSource = new CancellationTokenSource();
Task.Run(async () =>
{
try
{
await ExecuteEodPositionSettleAsync(userInfo, volType, useClosePrice, earliestTradeDate, latestTradeDate, taskId);
}
catch (OperationCanceledException)
{
LogFactory.GetLogger("日终持仓结算").Info($"异步日终持仓结算任务 {taskId} 已被取消");
}
catch (Exception ex)
{
LogFactory.GetLogger("日终持仓结算").Error($"异步日终持仓结算任务 {taskId} 执行失败: {ex.Message}", ex);
}
});
return JsonSuccess($"日终持仓结算任务已启动,任务ID: {taskId},预计处理 {estimatedDays} 个交易日,从 {earliestTradeDate:yyyy-MM-dd} 到 {latestTradeDate:yyyy-MM-dd}。任务将在后台异步执行。");
}
catch (Exception ex)
{
return JsonError($"启动任务失败: {ex.Message}");
}
}
/// <summary>
/// 异步执行日终持仓结算
/// </summary>
/// <param name="userInfo">用户信息</param>
/// <param name="volType">波动率类型</param>
/// <param name="useClosePrice">是否使用收盘价</param>
/// <param name="startDate">开始日期</param>
/// <param name="endDate">结束日期</param>
/// <param name="taskId">任务ID</param>
/// <returns></returns>
private async Task ExecuteEodPositionSettleAsync(OptUserInfo userInfo, string volType, bool useClosePrice,
DateTime startDate, DateTime endDate, string taskId)
{
var processedDates = new List<DateTime>();
var currentDate = startDate;
LogFactory.GetLogger("日终持仓结算").Info($"开始执行异步日终持仓结算任务 {taskId},从 {startDate:yyyy-MM-dd} 到 {endDate:yyyy-MM-dd}");
try
{
while (currentDate <= endDate)
{
LogFactory.GetLogger("日终持仓结算").Info($"任务 {taskId}: 正在处理日期 {currentDate:yyyy-MM-dd}");
// 创建结算请求对象
var request = new EodSettlementRequest(userInfo)
{
VolType = volType,
UseClosePrice = useClosePrice,
SettleDate = currentDate,
ClientIds = null,
DelayUnderlyIds = new List<int>()
};
// 获取结算配置
var settlementConfig = PS.Config.GetSettlementConfig();
// 获取取消令牌
CancellationToken cancellationToken = CancellationToken.None;
// 创建任务管理器
var taskManager = new SimpleTaskManager();
// 在Task.Run中执行CPU密集型操作
await Task.Run(() =>
{
// 创建结算上下文
var currentContext = new EodSettlementContextV2(request, settlementConfig, cancellationToken);
// 创建服务实例
var currentEodPositionService = new EodPositionSettleService(currentContext);
// 执行当前日期的结算
currentEodPositionService.Execute(volType, useClosePrice, taskManager);
});
processedDates.Add(currentDate);
currentDate = BLL.valuedateBLL.GetNonHoliday(currentDate.AddDays(1));
// 每处理一个日期后稍作延迟,避免过度占用系统资源
await Task.Delay(100);
}
LogFactory.GetLogger("日终持仓结算").Info($"异步日终持仓结算任务 {taskId} 执行完成,共处理了 {processedDates.Count} 个交易日");
}
catch (Exception ex)
{
LogFactory.GetLogger("日终持仓结算").Error($"异步日终持仓结算任务 {taskId} 在处理日期 {currentDate:yyyy-MM-dd} 时发生错误: {ex.Message}", ex);
throw;
}
}
#endregion
}
/// <summary>
/// 简单的任务管理器实现
/// </summary>
public class SimpleTaskManager : IAsyncTaskManager
{
/// <summary>
/// 设置任务步骤
/// </summary>
/// <param name="step">步骤描述</param>
public void SetTaskStep(string step)
{
// 可以在这里记录日志或更新进度
LogFactory.GetLogger("日终持仓结算").Info($"任务步骤: {step}");
}
/// <summary>
/// 等待任务完成
/// </summary>
/// <param name="tasks">要等待的任务数组</param>
public void WaitTasks(params Task[] tasks)
{
if (tasks is null || tasks.Length < 1)
{
return;
}
if (tasks.Any(n => n == null))
{
tasks = tasks.Where(n => n != null).ToArray();
if (tasks.Length < 1)
{
return;
}
}
foreach (var task in tasks)
{
task.ContinueWith(t =>
{
//!t.Exception.InnerExceptions.All(n => n is OperationCanceledException)
if (t.Exception != null)
{
LogFactory.GetLogger("日终结算").Error(t.Exception, "");
}
});
}
Task.WaitAll(tasks);
}
}
}