using SqlSugar; namespace Admin.NET.Plugin.AiDOP.DataPlatform.MdpRebuild; /// /// 把 L1–L3 日值抄进 ado_kpi_baseline_snapshot。 /// 窗口与 KPI 回算一致:当日及前 13 天(dayOffset = 13 … 0)。 /// 调用方必须自己保证这次抄的是全量重算之后的结果。 /// public sealed class KpiBaselineSnapshotService : ITransient { public const int WindowDays = 14; public static readonly long[] G0TenantIds = [ 797403760988229, 824585161322565, 838257186181189 ]; private readonly ISqlSugarClient _db; public KpiBaselineSnapshotService(ISqlSugarClient db) => _db = db; public async Task TakeAsync(string snapshotCode, CancellationToken cancellationToken = default) { if (string.IsNullOrWhiteSpace(snapshotCode)) throw new ArgumentException("snapshotCode 不能为空", nameof(snapshotCode)); var code = snapshotCode.Trim(); var tenants = string.Join(",", G0TenantIds); var written = 0; foreach (var (table, lvl) in new (string table, string lvl)[] { ("ado_s9_kpi_value_l1_day", "L1"), ("ado_s9_kpi_value_l2_day", "L2"), ("ado_s9_kpi_value_l3_day", "L3") }) { written += await _db.Ado.ExecuteCommandAsync( $""" INSERT INTO ado_kpi_baseline_snapshot (snapshot_code, tenant_id, factory_id, module_code, metric_code, lvl, biz_date, metric_value, target_value, result_status) SELECT @code, tenant_id, factory_id, module_code, metric_code, @lvl, biz_date, metric_value, target_value, NULL FROM {table} WHERE is_deleted = 0 AND tenant_id IN ({tenants}) AND biz_date BETWEEN DATE_SUB(CURDATE(), INTERVAL {WindowDays - 1} DAY) AND CURDATE() ON DUPLICATE KEY UPDATE metric_value = VALUES(metric_value), target_value = VALUES(target_value), result_status = VALUES(result_status), taken_at = CURRENT_TIMESTAMP(3) """, new { code, lvl }); cancellationToken.ThrowIfCancellationRequested(); } return written; } }