MdpDbSyncRebuildTrigger.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. using Admin.NET.Plugin.AiDOP.DataPlatform.MdpRebuild;
  2. using Admin.NET.Plugin.AiDOP.Entity.DataPlatform;
  3. using Microsoft.Extensions.Logging;
  4. namespace Admin.NET.Plugin.AiDOP.DataPlatform;
  5. /// <summary>
  6. /// 方式甲完成贴源抽取后,按任务消费模块触发既有模块重算。
  7. /// 只负责编排,不复制任何 S1-S7 转换或 KPI 逻辑。
  8. /// </summary>
  9. public sealed class MdpDbSyncRebuildTrigger : ITransient
  10. {
  11. private readonly ISqlSugarClient _db;
  12. private readonly ModuleRebuildService _rebuild;
  13. private readonly ILogger<MdpDbSyncRebuildTrigger> _logger;
  14. public MdpDbSyncRebuildTrigger(
  15. ISqlSugarClient db,
  16. ModuleRebuildService rebuild,
  17. ILogger<MdpDbSyncRebuildTrigger> logger)
  18. {
  19. _db = db;
  20. _rebuild = rebuild;
  21. _logger = logger;
  22. }
  23. public async Task<IReadOnlyList<string>> EnqueueForTaskAsync(
  24. MdpSyncTask task,
  25. long tenantId,
  26. long factoryId,
  27. string triggerType,
  28. CancellationToken cancellationToken,
  29. long? requestedBy = null)
  30. {
  31. if (tenantId <= 0)
  32. throw new InvalidOperationException("方式甲触发模块重算时 tenantId 必须大于 0");
  33. var modules = ParseModules(task.ConsumerModules);
  34. if (modules.Count == 0)
  35. modules = await InferModulesAsync(task, tenantId, cancellationToken);
  36. var accepted = new List<string>();
  37. var rejected = new List<string>();
  38. foreach (var module in modules)
  39. {
  40. cancellationToken.ThrowIfCancellationRequested();
  41. var (status, body) = await _rebuild.EnqueueAsync(
  42. module,
  43. tenantId,
  44. factoryId > 0 && factoryId != tenantId ? factoryId : 1,
  45. requestedBy,
  46. triggerType: triggerType,
  47. cancellationToken);
  48. if (status == 202)
  49. {
  50. accepted.Add(module);
  51. continue;
  52. }
  53. _logger.LogWarning(
  54. "方式甲任务 {TaskCode} 未能触发 {Module} 重算,status={Status} message={Message}",
  55. task.TaskCode, module, status, body.Message);
  56. rejected.Add($"{module}({status}:{body.Message})");
  57. }
  58. if (rejected.Count > 0)
  59. throw new InvalidOperationException($"方式甲抽取成功,但模块重算入队失败:{string.Join(";", rejected)}");
  60. return accepted;
  61. }
  62. internal static List<string> ParseModules(string? raw)
  63. {
  64. if (string.IsNullOrWhiteSpace(raw))
  65. return [];
  66. return raw
  67. .Split([',', ';', '|', ' ', '\r', '\n'], StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
  68. .Select(x => x.ToUpperInvariant())
  69. .Where(MdpRebuildScope.RebuildModules.Contains)
  70. .Distinct(StringComparer.OrdinalIgnoreCase)
  71. .OrderBy(x => x, StringComparer.OrdinalIgnoreCase)
  72. .ToList();
  73. }
  74. private async Task<List<string>> InferModulesAsync(
  75. MdpSyncTask task,
  76. long tenantId,
  77. CancellationToken cancellationToken)
  78. {
  79. var jobCode = string.IsNullOrWhiteSpace(task.JobCode) ? task.TaskCode : task.JobCode;
  80. var codes = await _db.Queryable<MdpEntity>()
  81. .Where(x => x.Status == 1
  82. && (x.TenantId == tenantId || x.TenantId == 0)
  83. && (x.JobId == task.TaskCode || x.JobId == jobCode))
  84. .Select(x => x.EntityCode)
  85. .ToListAsync(cancellationToken);
  86. var modules = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
  87. foreach (var code in codes)
  88. {
  89. var prefix = code.Length >= 2 ? code[..2].ToUpperInvariant() : "";
  90. if (MdpRebuildScope.RebuildModules.Contains(prefix))
  91. modules.Add(prefix);
  92. var std = MdpStdObjectCatalog.Find(code);
  93. if (std != null && MdpRebuildScope.RebuildModules.Contains(std.Module))
  94. modules.Add(std.Module);
  95. }
  96. return modules.OrderBy(x => x, StringComparer.OrdinalIgnoreCase).ToList();
  97. }
  98. }