namespace Admin.NET.Plugin.AiDOP.Supply; /// /// S3 MDP 运行监控。 /// [ApiDescriptionSettings(Order = 320, Description = "S3 MDP运行监控")] [Route("api/Supply")] [AllowAnonymous] [NonUnify] public class S3MdpMonitorService : IDynamicApiController, ITransient { private readonly ISqlSugarClient _db; public S3MdpMonitorService(ISqlSugarClient db) { _db = db; } [DisplayName("S3 MDP最近运行状态")] [HttpGet("s3-mdp-monitor/latest")] public async Task GetLatest() { return await _db.Ado.SqlQuerySingleAsync( $"{SelectColumnsSql()} FROM mdp_transform_run_log WHERE job_code='S3_MDP_SYNC_TRANSFORM' ORDER BY start_time DESC, id DESC LIMIT 1") ?? new S3MdpRunLogRow(); } [DisplayName("S3 MDP运行日志列表")] [HttpGet("s3-mdp-monitor/list")] public async Task GetList([FromQuery] S3MdpMonitorListInput input) { var page = input.Page <= 0 ? 1 : input.Page; var pageSize = input.PageSize <= 0 ? 10 : input.PageSize; var offset = (page - 1) * pageSize; var where = new List { "job_code='S3_MDP_SYNC_TRANSFORM'" }; var pars = new List(); if (!string.IsNullOrWhiteSpace(input.BatchId)) { where.Add("batch_id LIKE @BatchId"); pars.Add(new SugarParameter("@BatchId", $"%{input.BatchId.Trim()}%")); } if (!string.IsNullOrWhiteSpace(input.Status)) { where.Add("status=@Status"); pars.Add(new SugarParameter("@Status", input.Status.Trim().ToUpperInvariant())); } if (input.StartTime.HasValue) { where.Add("start_time >= @StartTime"); pars.Add(new SugarParameter("@StartTime", input.StartTime.Value)); } if (input.EndTime.HasValue) { where.Add("start_time <= @EndTime"); pars.Add(new SugarParameter("@EndTime", input.EndTime.Value)); } var whereSql = string.Join(" AND ", where); var total = await _db.Ado.GetIntAsync($"SELECT COUNT(1) FROM mdp_transform_run_log WHERE {whereSql}", pars); var list = await _db.Ado.SqlQueryAsync( $""" {SelectColumnsSql()} FROM mdp_transform_run_log WHERE {whereSql} ORDER BY start_time DESC, id DESC LIMIT {pageSize} OFFSET {offset} """, pars); return new { total, page, pageSize, list }; } [DisplayName("S3 MDP运行日志详情")] [HttpGet("s3-mdp-monitor/detail/{id}")] public async Task GetDetail(long id) { var row = await _db.Ado.SqlQuerySingleAsync( $"{SelectColumnsSql()} FROM mdp_transform_run_log WHERE id=@Id LIMIT 1", new SugarParameter("@Id", id)); return row ?? throw Oops.Oh("运行日志不存在"); } private static string SelectColumnsSql() { return """ SELECT id AS Id, tenant_id AS TenantId, job_code AS JobCode, job_name AS JobName, trigger_type AS TriggerType, batch_id AS BatchId, status AS Status, start_time AS StartTime, end_time AS EndTime, duration_ms AS DurationMs, stage_rows AS StageRows, standard_rows AS StandardRows, dwd_rows AS DwdRows, error_message AS ErrorMessage, summary_json AS SummaryJson, create_time AS CreateTime, update_time AS UpdateTime """; } } public sealed class S3MdpMonitorListInput { public string? BatchId { get; set; } public string? Status { get; set; } public DateTime? StartTime { get; set; } public DateTime? EndTime { get; set; } public int Page { get; set; } = 1; public int PageSize { get; set; } = 10; } public sealed class S3MdpRunLogRow { public long Id { get; set; } public long TenantId { get; set; } public string? JobCode { get; set; } public string? JobName { get; set; } public string? TriggerType { get; set; } public string? BatchId { get; set; } public string? Status { get; set; } public DateTime? StartTime { get; set; } public DateTime? EndTime { get; set; } public int? DurationMs { get; set; } public int? StageRows { get; set; } public int? StandardRows { get; set; } public int? DwdRows { get; set; } public string? ErrorMessage { get; set; } public string? SummaryJson { get; set; } public DateTime? CreateTime { get; set; } public DateTime? UpdateTime { get; set; } }