- 复用 HostedTaskService 定时器轮询待处理的 OA 移动审批状态 - 增加单实例防重入控制,避免同一进程内重复同步 - 新增 Erp.TradeApprovalOaSyncIntervalSeconds 配置,默认 30 秒 - 支持在 Admin 全局配置页修改查询间隔,保存后立即生效,无需重启 - 补充 AppConfig 初始化 SQL,不再依赖 PowerJob 或 XXL-JOB 外部调度
206 lines
6.7 KiB
C#
206 lines
6.7 KiB
C#
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<HostedTaskService>();
|
|
|
|
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<IServerAddressesFeature>().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;
|
|
}
|
|
}
|
|
}
|