using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server.Features; using YLErp.DBModels.Consts; using YLErp.Modules.AppModule; using YLErp.Modules.EodModule.SettlementModule; using YLErp.Modules.RiskEngine; using YLErp.Modules.RiskModule; using YLErp.Modules.SuperviseReportModule.SAC.Service; using YLErp.Modules.TradeModule; using YLErp.Modules.TradeRiskCalcModule; namespace YLErp.Web.App { //-------------------------------------- // 后台执行任务 //-------------------------------------- public class HostedTaskService : IHostedService { Timer _timer, _timerMonitor; private int _tradeApprovalOaSyncRunning; private DateTime _lastTradeApprovalOaSyncTime = DateTime.MinValue; private readonly IYcLogger _logger = LogFactory.GetLogger(); private readonly IServer server; private readonly IHostApplicationLifetime hostApplicationLifetime; public HostedTaskService(IServer server, IHostApplicationLifetime hostApplicationLifetime) { this.server = server; this.hostApplicationLifetime = hostApplicationLifetime; } private void TimerExecute(object state) { if (state != null) { Task.Run(() => { try { EodTaskRunner.Execute(); } catch (Exception ex) { LogFactory.GetLogger("EodTaskRunner").Error(ex); } }); } TrySyncTradeApprovalOaStatus(); if (AppHelper.RunTradeRiskCalcV2) { Task.Run(() => { var index = 0; var voltypes = new string[5]; if (AppHelper.IsSupportVolTypeOnRiskCalc("对冲")) { voltypes[index++] = "对冲"; } if (AppHelper.IsSupportVolTypeOnRiskCalc("持仓")) { voltypes[index++] = "持仓"; } if (AppHelper.IsSupportVolTypeOnRiskCalc("交易曲面")) { voltypes[index++] = "交易曲面"; } if (AppHelper.IsSupportVolTypeOnRiskCalc("场内实时持仓API")) { AppContext.SetSwitch("场内实时持仓API", true); } TradeRiskCalcTaskRunner.Execute(voltypes); }); } Task.Run(() => { try { if (PS.Config.ErpElement.SecuritiesEnvironment) { ReportService.ListensResponse(); } } catch { } }); } private void TrySyncTradeApprovalOaStatus() { var intervalSeconds = PS.Config?.ErpElement.TradeApprovalOaSyncIntervalSeconds ?? 30; if (intervalSeconds <= 0) { intervalSeconds = 30; } if (_lastTradeApprovalOaSyncTime != DateTime.MinValue && DateTime.Now - _lastTradeApprovalOaSyncTime < TimeSpan.FromSeconds(intervalSeconds)) { return; } if (Interlocked.CompareExchange(ref _tradeApprovalOaSyncRunning, 1, 0) != 0) { return; } Task.Run(() => { try { var results = new TradeApprovalOAService(new OptUserInfo(0, "系统移动审批同步", OptUserFrom.System)) .SyncPendingStatuses(); _logger.Info($"OA 移动审批状态定时同步完成,处理数量:{results.Count}"); } catch (Exception ex) { _logger.Error("OA 移动审批状态定时同步失败", ex); } finally { _lastTradeApprovalOaSyncTime = DateTime.Now; Interlocked.Exchange(ref _tradeApprovalOaSyncRunning, 0); } }); } public Task StartAsync(CancellationToken cancellationToken) { object _state = System.Diagnostics.Debugger.IsAttached ? null : this; _timer = new Timer(TimerExecute, _state, 1000, 2000); _timerMonitor = new Timer(state => { try { if (PS.Config.ErpElement.IsCalcRealtimeWarning) { WarningService.QuotaMonitorMsgQuery(); } } catch { } }, _state, 100000, 100000); Modules.DataCacheModule.DataCacheManager.StartUpdate(); // 项目启动时初始化项目YLErpWebUrl地址配置 hostApplicationLifetime.ApplicationStarted.Register( () => { var address = server.Features.Get().Addresses?.FirstOrDefault()?.Replace("*", "localhost"); if (string.IsNullOrEmpty(address)) { return; } // 更新YLErpWebUrl配置 var count = new AppConfigService(OptUserInfo.SystemUser).SaveYLWebApiConfig(address); if (count > 0) { PS.SetConfig(ConsAppConfig.YLErpWebUrlConfig, address); } // 预热风控引擎:加载规则与应用到内存,并预编译所有规则 Task.Run(() => { try { RiskEngineService.GetInstance().Preload(); } catch (Exception ex) { LogFactory.GetLogger("HostedTaskService").Error("[风控引擎] 启动预热失败", ex); } }); }); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { if (_timer != null) { _timer.Dispose(); _timer = null; } if (_timerMonitor != null) { _timerMonitor.Dispose(); _timerMonitor = null; } return Task.CompletedTask; } } }