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;
}
}