using Admin.NET.Plugin.AiDOP.Entity.DataPlatform; namespace Admin.NET.Plugin.AiDOP.DataPlatform.HotWatch; /// 热回读联调:手工登记 / 立即轮询。 [ApiDescriptionSettings(Order = 329, Description = "MDP 热回读运维")] [Route("api/aidop/mdp-hot-watch")] [AllowAnonymous] [NonUnify] public class MdpHotWatchAdminService : IDynamicApiController, ITransient { private readonly MdpHotWatchService _hotWatch; private readonly ISqlSugarClient _db; public MdpHotWatchAdminService(MdpHotWatchService hotWatch, ISqlSugarClient db) { _hotWatch = hotWatch; _db = db; } public sealed class EnrollWorkOrderInput { public string WorkOrd { get; set; } = ""; public string? Domain { get; set; } public long TenantId { get; set; } } [DisplayName("登记工单热回读")] [HttpPost("enroll-work-order")] public async Task EnrollWorkOrder([FromBody] EnrollWorkOrderInput input, CancellationToken ct = default) { if (input == null || string.IsNullOrWhiteSpace(input.WorkOrd)) throw Oops.Oh("WorkOrd 不能为空"); var domain = string.IsNullOrWhiteSpace(input.Domain) ? "8010" : input.Domain.Trim(); await _hotWatch.EnrollAsync( "WORK_ORDER", input.WorkOrd.Trim(), domain, new[] { "WorkOrdMaster", "WorkOrdRouting", "PeriodSequenceDet" }, input.TenantId, ct: ct); return new { ok = true, workOrd = input.WorkOrd.Trim(), domain }; } [DisplayName("热回读轮询一次")] [HttpPost("poll-once")] public async Task PollOnce([FromQuery] int take = 100, CancellationToken ct = default) { var (polled, changed, terminated) = await _hotWatch.PollOnceAsync(take <= 0 ? 100 : take, ct); return new { ok = true, polled, changed, terminated }; } public sealed class ForceRepollInput { public string BizKey { get; set; } = ""; public string? BizType { get; set; } } /// 清空快照哈希,下一轮 poll 必走变更写回(联调)。 [DisplayName("强制重读业务键")] [HttpPost("force-repoll")] public async Task ForceRepoll([FromBody] ForceRepollInput input, CancellationToken ct = default) { if (input == null || string.IsNullOrWhiteSpace(input.BizKey)) throw Oops.Oh("BizKey 不能为空"); var key = input.BizKey.Trim(); var type = string.IsNullOrWhiteSpace(input.BizType) ? null : input.BizType.Trim(); var q = _db.Queryable().Where(x => x.BizKey == key && x.Status == 0); if (!string.IsNullOrWhiteSpace(type)) q = q.Where(x => x.BizType == type); var rows = await q.ToListAsync(ct); foreach (var w in rows) { w.LastSnapshotHash = null; w.UpdateTime = DateTime.Now; await _db.Updateable(w) .UpdateColumns(x => new { x.LastSnapshotHash, x.UpdateTime }) .ExecuteCommandAsync(ct); } var (polled, changed, terminated) = await _hotWatch.PollOnceAsync(Math.Max(100, rows.Count), ct); return new { ok = true, cleared = rows.Count, polled, changed, terminated }; } }