| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- using Admin.NET.Plugin.AiDOP.Infrastructure;
- using Admin.NET.Plugin.AiDOP.Order;
- using Admin.NET.Plugin.AiDOP.ProcurementExecution;
- using Admin.NET.Plugin.AiDOP.Production;
- using Admin.NET.Plugin.AiDOP.Supply;
- using Furion.Schedule;
- using Microsoft.Extensions.DependencyInjection;
- using Microsoft.Extensions.Logging;
- using SqlSugar;
- using System.Text.Json;
- namespace Admin.NET.Plugin.AiDOP.Job;
- /// <summary>
- /// 应用启动后按 S1→S2→S3→S4 顺序执行 MDP 全量同步,构建模块 KPI 汇总与 KPI 原子聚合层。
- /// 新环境发布后无需等待 hourly 任务即可在看板筛选中看到数据。
- /// </summary>
- [JobDetail("job_smart_ops_kpi_mdp_bootstrap", Description = "智慧运营KPI:启动时按序执行S1→S2→S3→S4 MDP同步(含原子聚合层)", GroupName = "default", Concurrent = false)]
- [PeriodSeconds(1, TriggerId = "trigger_smart_ops_kpi_mdp_bootstrap", Description = "应用启动后立即执行一次", MaxNumberOfRuns = 1, RunOnStart = true)]
- public class SmartOpsKpiMdpBootstrapJob : IJob
- {
- private const string EnvBootstrapEnabled = "AIDOP_MDP_BOOTSTRAP_ENABLED";
- private readonly IServiceScopeFactory _scopeFactory;
- private readonly ILogger _logger;
- public SmartOpsKpiMdpBootstrapJob(IServiceScopeFactory scopeFactory, ILoggerFactory loggerFactory)
- {
- _scopeFactory = scopeFactory;
- _logger = loggerFactory.CreateLogger(nameof(SmartOpsKpiMdpBootstrapJob));
- }
- public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
- {
- if (!IsBootstrapEnabled(Environment.GetEnvironmentVariable(EnvBootstrapEnabled)))
- {
- _logger.LogInformation(
- "SmartOpsKpiMdpBootstrapJob 被环境变量 {EnvironmentVariable}=false 禁用",
- EnvBootstrapEnabled);
- return;
- }
- using var scope = _scopeFactory.CreateScope();
- var db = scope.ServiceProvider.GetRequiredService<ISqlSugarClient>();
- try
- {
- AidopTenantMigration.EnsureKpiAtomicTable(db);
- _logger.LogInformation("SmartOpsKpiMdpBootstrapJob: ado_smart_ops_kpi_atomic_day 已就绪");
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "SmartOpsKpiMdpBootstrapJob: 原子聚合表初始化失败");
- }
- await RunStepAsync("S1", stoppingToken, async sp =>
- {
- var catalog = sp.GetRequiredService<Admin.NET.Plugin.AiDOP.DataPlatform.S1Refresh.S1MdpScopeCatalog>();
- var rebuild = sp.GetRequiredService<Admin.NET.Plugin.AiDOP.DataPlatform.S1Refresh.S1DashboardRebuildService>();
- var scopes = await catalog.ListEnabledScopesAsync(stoppingToken);
- var accepted = 0;
- foreach (var runScope in scopes)
- {
- var (status, _) = await rebuild.EnqueueAsync(runScope.TenantId, runScope.FactoryId, null, "BOOTSTRAP", stoppingToken);
- if (status == 202) accepted++;
- }
- return new { scopes = scopes.Count, accepted };
- });
- await RunStepAsync("S2", stoppingToken, async sp =>
- {
- var payload = await Admin.NET.Plugin.AiDOP.DataPlatform.MdpRebuild.ModuleRebuildJobRunner
- .EnqueueEnabledScopesAsync(sp, "S2", "BOOTSTRAP", stoppingToken, _logger);
- return payload;
- });
- await RunStepAsync("S3", stoppingToken, async sp =>
- {
- var payload = await Admin.NET.Plugin.AiDOP.DataPlatform.MdpRebuild.ModuleRebuildJobRunner
- .EnqueueEnabledScopesAsync(sp, "S3", "BOOTSTRAP", stoppingToken, _logger);
- return payload;
- });
- await RunStepAsync("S4", stoppingToken, async sp =>
- {
- var payload = await Admin.NET.Plugin.AiDOP.DataPlatform.MdpRebuild.ModuleRebuildJobRunner
- .EnqueueEnabledScopesAsync(sp, "S4", "BOOTSTRAP", stoppingToken, _logger);
- return payload;
- });
- _logger.LogInformation("SmartOpsKpiMdpBootstrapJob: 全部 MDP 引导同步已完成");
- }
- internal static bool IsBootstrapEnabled(string? raw) =>
- !bool.TryParse(raw, out var enabled) || enabled;
- private async Task RunStepAsync(string step, CancellationToken stoppingToken, Func<IServiceProvider, Task<object>> action)
- {
- using var scope = _scopeFactory.CreateScope();
- try
- {
- stoppingToken.ThrowIfCancellationRequested();
- var payload = await action(scope.ServiceProvider);
- _logger.LogInformation("SmartOpsKpiMdpBootstrapJob {Step} 完成 {Payload}", step, JsonSerializer.Serialize(payload));
- }
- catch (Admin.NET.Plugin.AiDOP.DataPlatform.S1Refresh.S1MdpAlreadyRunningException)
- {
- _logger.LogInformation("SmartOpsKpiMdpBootstrapJob {Step} 跳过:已有全量任务在执行", step);
- }
- catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
- {
- _logger.LogInformation("SmartOpsKpiMdpBootstrapJob {Step} 收到停止信号", step);
- throw;
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "SmartOpsKpiMdpBootstrapJob {Step} 执行失败,继续后续步骤", step);
- }
- }
- }
|